React State Management
Overview
State management in React ranges from local component state to global stores. Choose a solution based on app complexity.
Context API
Built-in way to share state across component tree without prop drilling:
// createContext and Provider
const ThemeContext = createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return <ThemedButton />;
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={theme}>Theme is {theme}</button>;
} useReducer Hook
An alternative for complex local state logic:
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
Count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
} Redux Basics
Popular library for predictable global state. Core concepts: store, actions, reducers:
// counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
export const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: state => { state.value += 1 },
decrement: state => { state.value -= 1 }
}
});
export const { increment, decrement } = counterSlice.actions;
// store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
export const store = configureStore({ reducer: { counter: counterReducer } });
// Counter.js
import { useSelector, useDispatch } from 'react-redux';
function Counter() {
const count = useSelector(state => state.counter.value);
const dispatch = useDispatch();
return (
<div>
{count}
<button onClick={() => dispatch(increment())}>+</button>
</div>
);
} Zustand
Lightweight state management using hooks:
import create from 'zustand';
const useStore = create(set => ({
count: 0,
increment: () => set(state => ({ count: state.count + 1 })),
}));
function Counter() {
const { count, increment } = useStore();
return (
<div>
{count}
<button onClick={increment}>+</button>
</div>
);
}