State Management in React: Context API and Introduction to Redux
Introduction to State Management
State management is a critical concept in React for:
- Sharing data across components.
- Keeping the UI in sync with the application state.
React provides two primary ways to manage state:
- Context API: For moderate state sharing across a component tree.
- Redux: For complex state management with predictable updates.
Context API
The Context API allows you to share state across the component tree without passing props down manually at every level.
2.1 When to Use Context API
- Avoiding “prop drilling” (passing props down multiple levels).
- Sharing global data like user authentication, themes, or language preferences.
2.2 Setting Up Context API
Create a Context
import React, { createContext, useState } from 'react';
const UserContext = createContext();
export default UserContext;
Provide Context Wrap your app with the Provider
component and pass the shared data.
import React, { useState } from 'react';
import UserContext from './UserContext';
function App() {
const [user, setUser] = useState({ name: 'John', age: 30 });
return (
<UserContext.Provider value={{ user, setUser }}>
<ChildComponent />
</UserContext.Provider>
);
}
export default App;
Consume Context Use the useContext
hook to access the shared state in child components.
import React, { useContext } from 'react';
import UserContext from './UserContext';
function ChildComponent() {
const { user, setUser } = useContext(UserContext);
return (
<div>
<h1>{user.name}</h1>
<button onClick={() => setUser({ ...user, age: user.age + 1 })}>
Increment Age
</button>
</div>
);
}
export default ChildComponent;
Advantages of Context API
- Built into React (no additional library required).
- Simplifies prop drilling.
- Easy to set up for small to medium-scale applications.
Introduction to Redux
When to Use Redux
- Large-scale applications with deeply nested components.
- Sharing state across unrelated components.
- Handling complex state logic or asynchronous updates.
Core Concepts of Redux
- Store: The single source of truth for the application’s state.
- Actions: Plain JavaScript objects that describe what to do.
- Reducers: Pure functions that update the state based on actions.
- Dispatch: A method to send actions to the reducer.
Setting Up Redux
Step 1: Install Redux
npm install redux react-redux
Step 2: Create a Redux Store
import { createStore } from 'redux';
// Initial State
const initialState = {
count: 0,
};
// Reducer Function
function counterReducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
case 'DECREMENT':
return { ...state, count: state.count - 1 };
default:
return state;
}
}
// Create Store
const store = createStore(counterReducer);
export default store;
Step 3: Connect Redux to React
Wrap your app with the
Provider
component.
import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import Counter from './Counter';
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
export default App;
Use
useSelector
to access state anduseDispatch
to dispatch actions.
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
function Counter() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();
return (
<div>
<h1>{count}</h1>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>
Increment
</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>
Decrement
</button>
</div>
);
}
export default Counter;
Comparison: Context API vs. Redux
Feature | Context API | Redux |
---|---|---|
Complexity | Low | High |
Learning Curve | Easy | Steeper |
Ideal For | Simple to medium state sharing | Complex and large-scale apps |
Asynchronous Handling | Needs custom implementation | Built-in with middleware like redux-thunk |
Best Practices for State Management
- Keep State Minimal: Only store what’s necessary.
- Structure State Carefully: Organize state logically for easier maintenance.
- Use Context Sparingly: For frequent updates, consider alternatives to avoid re-rendering.
- Combine Tools: Use Context API for themes and Redux for app-wide complex state.