How to Manage State in React Apps with APIs: Redux, Context API, and Recoil Examples
Managing state in React apps with APIs can be done using various options, like Redux, Context API, and Recoil. Each method has its own benefits and works best in different situations. I'll provide examples for each below.
Redux:
Redux is a way to manage the state of JavaScript apps. It's often used for handling the state of larger applications.
Install Redux:
npm install redux react-redux
Example Usage:
Create Actions:
// actions.js export const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS'; export const fetchDataSuccess = (data) => ({ type: FETCH_DATA_SUCCESS, payload: data, });
Create Reducer:
// reducer.js import { FETCH_DATA_SUCCESS } from './actions'; const initialState = { data: [], }; const reducer = (state = initialState, action) => { switch (action.type) { case FETCH_DATA_SUCCESS: return { ...state, data: action.payload, }; default: return state; } }; export default reducer;
Create Store:
// store.js import { createStore } from 'redux'; import reducer from './reducer'; const store = createStore(reducer); export default store;
Use in Component:
// MyComponent.js import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { fetchDataSuccess } from './actions'; const MyComponent = () => { const dispatch = useDispatch(); const data = useSelector((state) => state.data); useEffect(() => { // Fetch data from API fetch('https://api.example.com/data') .then((response) => response.json()) .then((data) => dispatch(fetchDataSuccess(data))); }, [dispatch]); return ( <div> {data.map((item) => ( <p key={item.id}>{item.name}</p> ))} </div> ); }; export default MyComponent;
2. Context API:
The Context API is a part of React and is suitable for simpler state management needs.
Example Usage:
Create Context:
// DataContext.js import { createContext } from 'react'; const DataContext = createContext(); export default DataContext;
Create a Provider Component:
// DataProvider.js import React, { useState, useEffect } from 'react'; import DataContext from './DataContext'; const DataProvider = ({ children }) => { const [data, setData] = useState([]); useEffect(() => { // Fetch data from API fetch('https://api.example.com/data') .then((response) => response.json()) .then((data) => setData(data)); }, []); return ( <DataContext.Provider value={{ data }}> {children} </DataContext.Provider> ); }; export default DataProvider;
Use in Component:
// MyComponent.js import React, { useContext } from 'react'; import DataContext from './DataContext'; const MyComponent = () => { const { data } = useContext(DataContext); return ( <div> {data.map((item) => ( <p key={item.id}>{item.name}</p> ))} </div> ); }; export default MyComponent;
3. Recoil:
Recoil is a state-management library specifically designed for React.
Install Recoil:
npm install recoil
Example Usage:
Create Atoms:
// atoms.js import { atom } from 'recoil'; export const dataState = atom({ key: 'dataState', default: [], });
Use in Component:
// MyComponent.js import React from 'react'; import { useRecoilValue, useRecoilState } from 'recoil'; import { dataState } from './atoms'; const MyComponent = () => { const data = useRecoilValue(dataState); // Alternatively, if you need to modify the state // const [data, setData] = useRecoilState(dataState); return ( <div> {data.map((item) => ( <p key={item.id}>{item.name}</p> ))} </div> ); }; export default MyComponent;
Don't forget to pick the state management solution that works best for your app's requirements and complexity. For smaller apps, the Context API or Recoil might be enough, while Redux is usually better for bigger applications.