Local State vs Global State
Local State
Local state refers to data that is managed within a single component using the useState
or useReducer
hooks.
It is ideal for temporary data such as form inputs, toggles, and UI visibility.
import { useState } from 'react';
function Toggle() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? 'Hide' : 'Show'}
</button>
{isOpen && <p>This is toggled content.</p>}
</div>
);
}
Global State
Global state is data that needs to be accessible across multiple components or layers of the app,
such as user authentication, theme preferences, or language settings.
React does not include built-in global state management beyond the Context API
.
For more complex needs, external libraries like Redux or Zustand are used.
Context API
The Context API is React’s built-in solution for sharing state across the component tree without prop drilling.
Creating and Using Context
import { createContext, useContext, useState } from 'react';
// 1. Create context
const ThemeContext = createContext();
// 2. Provide context value
function ThemeProvider({ children }) {
const [darkMode, setDarkMode] = useState(false);
const toggleTheme = () => setDarkMode(prev => !prev);
return (
<ThemeContext.Provider value={{ darkMode, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
// 3. Consume context
function ThemeToggleButton() {
const { darkMode, toggleTheme } = useContext(ThemeContext);
return (
<button onClick={toggleTheme}>
Switch to {darkMode ? 'Light' : 'Dark'} Mode
</button>
);
}
Context is great for app-wide settings or simple shared state, but may become inefficient for large or rapidly changing data.
Introduction to Redux and Zustand
Redux
Redux is a popular and mature state management library that uses a centralized store, actions, and reducers to manage state. It’s useful for complex applications with deeply nested components or predictable state transitions.
Install Redux and React bindings:
npm install @reduxjs/toolkit react-redux
Example Redux store using Redux Toolkit:
// store.js
import { configureStore, createSlice } from '@reduxjs/toolkit';
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;
export const store = configureStore({
reducer: { counter: counterSlice.reducer }
});
Connect it to your app:
import { Provider, useDispatch, useSelector } from 'react-redux';
import { store, increment, decrement } from './store';
function Counter() {
const count = useSelector(state => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch(decrement())}>-</button>
<span>{count}</span>
<button onClick={() => dispatch(increment())}>+</button>
</div>
);
}
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
Zustand
Zustand is a minimal and intuitive state management library. It requires less boilerplate than Redux and works seamlessly with React.
Install Zustand:
npm install zustand
Create a global store:
import { create } from 'zustand';
const useStore = create(set => ({
count: 0,
increment: () => set(state => ({ count: state.count + 1 })),
decrement: () => set(state => ({ count: state.count - 1 }))
}));
Use it in components:
function Counter() {
const { count, increment, decrement } = useStore();
return (
<div>
<button onClick={decrement}>-</button>
<span>{count}</span>
<button onClick={increment}>+</button>
</div>
);
}
Conclusion
State management is a core part of any React application. Use local state for simple, component-specific data, the Context API for shared app-wide state, and tools like Redux or Zustand for complex or scalable scenarios. In the next post, we’ll explore how to fetch data from APIs and manage server state efficiently in React.
0 Comments