A guide to React-Redux’s modern state management
In this blog, we will learn about React-Redux’s modern state management.
React-Redux: React-Redux is the official React binding for Redux, a state management library. It allows React components to read data from a Redux store and dispatch actions to update the state.
Why use Redux in React?
React has local component state (useState, useReducer). But if you have global data (e.g., user login info, cart, theme) Many components need access to or modify the same data
- You have global data
- Multiple components need to share and update the same state
- You want predictable and traceable state updates((Action → Reducer → State)
- You want to persist or share state easily
Redux Architecture (Flow)
UI (React Component) triggers an Action: The UI (React component) detects a user interaction or event, such as a button click or form submission, and dispatches an action
Action describes what happened: The action contains a type that specifies what happened (e.g., ADD_ITEM, REMOVE_ITEM) and an optional payload that includes the necessary data (e.g., item details, updated values)
Reducer receives the action and updates the Store:
- The reducer is a pure function that receives the current state and the action dispatched.
- Based on the action’s type and payload, the reducer calculates the new state and returns it.
Store holds the new state: The store is the single source of truth for the application’s state. After the reducer updates the state, the store holds this new state.
UI re-renders with updated data:
- The React component uses useSelector to access the updated state from the Redux store.
- Whenever the store’s state changes, React automatically triggers a re-render of the UI with the updated data.
One-Way Data Flow Diagram:
UI --> dispatch(action) --> reducer --> new state --> UI updates
Redux Core Concepts: Architecture and Data Flow:
Store: The store is a centralized container that holds the entire state of your application.
Ex: import { createStore } from 'redux'; const store = createStore(rootReducer);
Actions: Actions are plain JavaScript objects and they must have a type property and may include additional data via a payload.
Ex: export const increment = () => ({ type: ‘INCREMENT’ });
export const decrement = () => ({ type: ‘DECREMENT’ });
Reducers: Reducers are pure modern functions that take the current state and an action, and return a new state. Based on the type of action, they determine how the state should change.
Ex: const reducer = (state = 0, action) => { switch(action.type) { case 'INCREMENT': return state + 1; case 'DECREMENT': return state - 1; default: return state;}}
Dispatch: Dispatch is the method used to send actions to the Redux store
Ex: dispatch(increment());
Setting Up Redux in a React Application:
step-by-step guide to setting up and using Redux with React.
Install Redux and React-Redux:
npm install redux react-redux
Create Your Store: Create a central store that holds your application’s state.
Ex: import { createStore } from 'redux'; import rootReducer from './reducers'; const store = createStore(rootReducer); export default store;
Provide the Store to the React App: your app with the <Provider> component from react-redux so that all components can access the Redux store.
Ex: import React from 'react'; import { Provider } from 'react-redux'; import store from './store'; import App from './App'; ReactDOM.render( <Provider store={store}> <App /> </Provider>);
Using Redux in Components: Reading State with useSelector
Ex: const count = useSelector(state => state.counter);
Dispatching Actions: Send actions to the Redux store
Ex: const dispatch = useDispatch(); dispatch(increment());
Highlights:
- Centralized State Management
- Predictable State Updates
- Improved Maintainability
- Debugging Tools
Things to Consider :
- Boilerplate Code
- Debugging Middleware or Async Flows Can Be Tricky