- Published on
Redux: State Management in React
- Authors
- Name
- Shelton Ma
1. What is Redux?
Redux is one of the most popular libraries for state management in React applications. It helps manage the state in a predictable way, ensuring that the data flows in a consistent manner across the application.
In Redux, state is handled globally and allows you to change the state from anywhere in the application instead of creating new objects every time state is changed.
2. Key Concepts in Redux
The lifecycle in Redux: Action
→ Dispatches Action
→ Reducers Update State
→ Re-renders Components
→ Components Update Props
→ Display Updated UI
Action
An Action describes what happens in your application. It’s an object that holds the information of the user’s event, and it communicates a change in the state. Actions are dispatched from any part of your app and are received by the store. They are plain JavaScript objects with a
type
property, which describes the action that occurred, but not how the state will change.Store
The Store is the single, authoritative source of state in your application. There is only one store per Redux application, and it handles both dispatching actions and receiving updates to state.
Reducers
Reducers are pure functions responsible for specifying how the state changes in response to an action. When an action is dispatched, the store sends the action to the appropriate reducer. The reducer uses the current state and action to return a new state.
3. Async with Redux
import React, { useReducer } from 'react';
import ReactDOM from 'react-dom';
const initialState = {
first_name: "John",
last_name: "Smith",
department: "operations"
};
function myReducer(state, action) {
switch (action.type) {
case 'changeDepartmentToIT':
return {
...state,
department: 'IT'
};
case 'changeDepartmentToSecurity':
return {
...state,
department: 'Security'
};
default:
throw new Error();
}
}
function ChangeUserDepartment() {
const [state, dispatch] = useReducer(myReducer, initialState);
return (
<div>
<p>First Name: {state.first_name}</p>
<p>Last Name: {state.last_name}</p>
<p>User Department: {state.department}</p>
<button onClick={() => dispatch({type: 'changeDepartmentToIT'})}>Change User Department to IT</button>
<button onClick={() => dispatch({type: 'changeDepartmentToSecurity'})}>Change User Department to Security</button>
</div>
);
}
4. Using Redux in Your Application
1. Install Redux and React-Redux
To start using Redux, you'll need to install both redux
and react-redux
(which binds Redux to React components):
pnpm install redux react-redux
2. Define Your Redux Store
Create Action Types
// actionTypes.ts export const INCREMENT = 'INCREMENT'; export const DECREMENT = 'DECREMENT';
Create Actions
// actions.ts import { INCREMENT, DECREMENT } from './actionTypes'; export const increment = () => ({ type: INCREMENT, }); export const decrement = () => ({ type: DECREMENT, });
Create Reducers
Reducers define how the state should change in response to actions. Here, we’ll have a simple reducer for the counter state:
// counterReducer.ts import { INCREMENT, DECREMENT } from './actionTypes'; const initialState = { count: 0, }; export const counterReducer = (state = initialState, action: any) => { switch (action.type) { case INCREMENT: return { ...state, count: state.count + 1 }; case DECREMENT: return { ...state, count: state.count - 1 }; default: return state; } };
Combine Reducers
If your application has multiple reducers, you can combine them into one using combineReducers:
// rootReducer.ts import { combineReducers } from 'redux'; import { counterReducer } from './counterReducer'; export const rootReducer = combineReducers({ counter: counterReducer, });
3. Create and Configure the Store
Now, let’s create the Redux store and pass in the rootReducer:
// store.ts
import { createStore } from 'redux';
import { rootReducer } from './rootReducer';
export const store = createStore(rootReducer);
4. Provide the Store to Your Application
In order to use Redux in your React components, you need to wrap your application with the Provider from react-redux. This makes the Redux store available to all components in the app.
// index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
5. Connect Redux State and Actions to Your Components
Now, let’s connect the Redux state and actions to a React component. For example, a Counter component:
// Counter.tsx
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { increment, decrement } from './actions';
export const Counter = () => {
const dispatch = useDispatch();
const count = useSelector((state: any) => state.counter.count);
return (
<div>
<h1>Counter: {count}</h1>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
</div>
);
};
In this component:
- We use useSelector to access the count state from the Redux store.
- We use useDispatch to dispatch actions when the user clicks the buttons.