REACT
React State Management: Syntax, Usage, and Examples
React state management controls how data flows and updates across components in a React application. Managing state efficiently ensures that UI elements react correctly to user interactions and data changes without unnecessary re-renders.
How to Manage State in React
React offers multiple ways to manage state, ranging from built-in hooks like useState
and useReducer
to external libraries that help with global state. The best approach depends on your application's complexity and the level of state sharing between components.
Using useState
for Local Component State
If your state only affects a single component, useState
is the simplest way to manage it.
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
The useState
function initializes state, and the setCount
function updates it when the user clicks the button.
Using useReducer
for Complex State Logic
When your state logic grows, useReducer
can provide better structure and clarity.
import React, { useReducer } from "react";
const initialState = { count: 0 };
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, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
</div>
);
}
export default Counter;
This approach helps when state changes follow a structured pattern, such as form submissions or undo/redo functionality.
When to Use React State Management
Handling Local Component State
Use useState
when a component needs to store and update simple data, such as input fields, toggles, or modals. Since useState
only updates state within its component, it works well for UI elements that don’t need to share state with others.
Managing Global State Across Components
If multiple components need access to the same data, managing global state helps keep everything synchronized. Examples include:
- Keeping a user logged in after authentication
- Storing theme preferences across different pages
- Managing cart data in an e-commerce application
Handling Server State
For real-time updates from an API, tools like React Query help fetch, cache, and sync server data efficiently. You might use this when handling search results, user profiles, or financial transactions that require live updates.
Examples of React State Management
Using React Context for Global State
React Context makes it easy to pass state between components without prop drilling.
import React, { createContext, useContext, useState } from "react";
const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
function ThemedComponent() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<div style={{ background: theme === "light" ? "#fff" : "#333", color: theme === "light" ? "#000" : "#fff" }}>
<p>Current Theme: {theme}</p>
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
Toggle Theme
</button>
</div>
);
}
export default function App() {
return (
<ThemeProvider>
<ThemedComponent />
</ThemeProvider>
);
}
Context helps when passing state deeply into multiple components, such as user authentication status or UI themes.
Using Redux for Large-Scale State Management
Redux is useful when your application requires a predictable, structured way to manage global state.
import { createStore } from "redux";
import { Provider, useDispatch, useSelector } from "react-redux";
const initialState = { count: 0 };
function counterReducer(state = initialState, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
const store = createStore(counterReducer);
function Counter() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();
return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
</div>
);
}
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
export default App;
Redux works well for enterprise-level applications where state needs to be accessed and updated from different parts of the application without direct component relationships.
Learn More About React State Management
Comparing Different State Management Approaches
Each state management approach has its strengths:
- Use
useState
for local component state like form inputs or UI toggles. - Use
useReducer
when managing complex state logic, such as step-based forms or interactive UI elements. - Use React Context for lightweight global state needs, like themes or authentication.
- Use Redux when multiple parts of an application require shared state updates, such as an online store's cart or user data.
Global State in React vs. Angular
React relies on hooks, Context API, and external libraries for state management. In contrast, Angular uses services and RxJS to handle global state changes. While React favors component-based reactivity, Angular integrates state management directly into its framework.
Choosing the Best State Management Approach
If your app is small, React’s built-in useState
and Context API may be enough. If your project grows, libraries like Zustand or Recoil provide flexible state management without the complexity of Redux. When building a large-scale application, Redux or MobX help maintain a structured state architecture.
Storing State in Local Storage
To persist state across page reloads, use local storage:
import { useState, useEffect } from "react";
function App() {
const [theme, setTheme] = useState(() => localStorage.getItem("theme") || "light");
useEffect(() => {
localStorage.setItem("theme", theme);
}, [theme]);
return (
<div>
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
Toggle Theme
</button>
</div>
);
}
export default App;
This method works well for preferences like dark mode or language settings.
Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.