Managing global state in a React application can be challenging, especially as the app scales. Redux is a powerful library that provides a predictable state container, allowing you to manage complex state interactions efficiently. In this article, we will explore three diverse examples of managing global state with Redux in React, helping you understand how to implement Redux effectively in your applications.
A simple counter application is a great way to illustrate how Redux can manage global state. This example will show how to increment and decrement a counter value across components.
// actions.js
export const increment = () => ({ type: 'INCREMENT' });
export const decrement = () => ({ type: 'DECREMENT' });
// reducer.js
const initialState = { count: 0 };
export const 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;
}
};
// store.js
import { createStore } from 'redux';
import { counterReducer } from './reducer';
const store = createStore(counterReducer);
// Counter.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './actions';
const Counter = () => {
const count = useSelector(state => state.count);
const dispatch = useDispatch();
return (
<div>
<h1>Counter: {count}</h1>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
</div>
);
};
export default Counter;
In many applications, managing user authentication state is crucial. This example illustrates how to manage user login status globally using Redux.
// actions.js
export const login = (user) => ({ type: 'LOGIN', payload: user });
export const logout = () => ({ type: 'LOGOUT' });
// reducer.js
const initialState = { isAuthenticated: false, user: null };
export const authReducer = (state = initialState, action) => {
switch (action.type) {
case 'LOGIN':
return { ...state, isAuthenticated: true, user: action.payload };
case 'LOGOUT':
return { ...state, isAuthenticated: false, user: null };
default:
return state;
}
};
// store.js
import { createStore } from 'redux';
import { authReducer } from './reducer';
const store = createStore(authReducer);
// Auth.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { login, logout } from './actions';
const Auth = () => {
const { isAuthenticated, user } = useSelector(state => state);
const dispatch = useDispatch();
const handleLogin = () => {
const user = { name: 'John Doe' };
dispatch(login(user));
};
return (
<div>
{isAuthenticated ? (
<div>
<h1>Welcome, {user.name}</h1>
<button onClick={() => dispatch(logout())}>Logout</button>
</div>
) : (
<button onClick={handleLogin}>Login</button>
)}
</div>
);
};
export default Auth;
A shopping cart is a common feature in e-commerce applications. This example demonstrates how to manage a shopping cart’s state using Redux, including adding and removing items.
// actions.js
export const addItem = (item) => ({ type: 'ADD_ITEM', payload: item });
export const removeItem = (itemId) => ({ type: 'REMOVE_ITEM', payload: itemId });
// reducer.js
const initialState = { items: [] };
export const cartReducer = (state = initialState, action) => {
switch (action.type) {
case 'ADD_ITEM':
return { ...state, items: [...state.items, action.payload] };
case 'REMOVE_ITEM':
return { ...state, items: state.items.filter(item => item.id !== action.payload) };
default:
return state;
}
};
// store.js
import { createStore } from 'redux';
import { cartReducer } from './reducer';
const store = createStore(cartReducer);
// Cart.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { addItem, removeItem } from './actions';
const Cart = () => {
const items = useSelector(state => state.items);
const dispatch = useDispatch();
const handleAddItem = () => {
const newItem = { id: Date.now(), name: 'New Item' };
dispatch(addItem(newItem));
};
return (
<div>
<h1>Shopping Cart</h1>
<button onClick={handleAddItem}>Add Item</button>
<ul>
{items.map(item => (
<li key={item.id}>
{item.name} <button onClick={() => dispatch(removeItem(item.id))}>Remove</button>
</li>
))}
</ul>
</div>
);
};
export default Cart;
These examples demonstrate effective ways to manage global state with Redux in React applications. By leveraging Redux, you can ensure that your application remains organized and maintainable, even as it grows in complexity.