Learn how to manage state effectively in React applications
Component-level state management
import { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
const [error, setError] = useState(null);
const increment = () => {
try {
setCount(prev => prev + 1);
} catch (err) {
setError('Failed to increment');
}
};
if (error) return Error: {error};
return (
Count: {count}
);
};
Sharing state across components
// ThemeContext.js
import { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prev => prev === 'light' ? 'dark' : 'light');
};
return (
{children}
);
};
// Using the context
const ThemedButton = () => {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
);
};
Managing complex state logic
import { useReducer } from 'react';
const initialState = {
todos: [],
loading: false,
error: null
};
function todoReducer(state, action) {
switch (action.type) {
case 'ADD_TODO':
return {
...state,
todos: [...state.todos, action.payload]
};
case 'REMOVE_TODO':
return {
...state,
todos: state.todos.filter(todo => todo.id !== action.payload)
};
case 'SET_LOADING':
return {
...state,
loading: action.payload
};
default:
return state;
}
}
const TodoList = () => {
const [state, dispatch] = useReducer(todoReducer, initialState);
const addTodo = (text) => {
dispatch({
type: 'ADD_TODO',
payload: { id: Date.now(), text }
});
};
return (
{state.loading ? (
Loading...
) : (
{state.todos.map(todo => (
- {todo.text}
))}
)}
);
};
Application-wide state management
// store/index.js
import { configureStore } from '@reduxjs/toolkit';
import authReducer from './authSlice';
import todoReducer from './todoSlice';
export const store = configureStore({
reducer: {
auth: authReducer,
todos: todoReducer
}
});
// Component usage
import { useSelector, useDispatch } from 'react-redux';
import { login } from './authSlice';
const LoginForm = () => {
const dispatch = useDispatch();
const { isAuthenticated } = useSelector(
state => state.auth
);
const handleLogin = (credentials) => {
dispatch(login(credentials));
};
return (
);
};