Master Redux: State Management with Examples and Best Practices
Redux is a powerful library for managing state in JavaScript applications. It is commonly used with libraries such as React or Angular for creating more predictable and maintainable applications. This guide introduces Redux and provides extensive examples of its many APIs.
Introduction to Redux
Redux is a predictable state container for JavaScript apps. It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. While Redux is most commonly used with React, it can be used with any other view library as well.
Core Concepts
At the heart of Redux are the following core concepts:
- Actions: These are payloads of information that send data from your application to your Redux store. Actions are the only source of information for the store.
- Reducers: These specify how the application’s state changes in response to actions sent to the store.
- Store: The store is the object that brings actions and reducers together. The store has the following responsibilities:
- Holds the application state.
- Allows access to state via
getState()
. - Allows state to be updated via
dispatch(action)
. - Registers listeners via
subscribe(listener)
. - Handles the unregistering of listeners.
Basic Example
Here is a basic example to get you started with Redux:
{` import { createStore } from 'redux'; // This is a reducer: a pure function with (state, action) => state signature. function counter(state = 0, action) { switch (action.type) { case 'INCREMENT': return state + 1; case 'DECREMENT': return state - 1; default: return state; } } // Create a Redux store holding the state of your app. let store = createStore(counter); // You can use the getState() method to retrieve the current state of the application. console.log(store.getState()); // To dispatch any actions to modify the state, use the dispatch() method. store.dispatch({ type: 'INCREMENT' }); console.log(store.getState()); store.dispatch({ type: 'DECREMENT' }); console.log(store.getState()); `}
API Examples
createStore
The createStore
function is used to create a new Redux store. It accepts three arguments: the root reducer, the initial state, and an optional enhancer.
{` import { createStore } from 'redux'; const initialState = { value: 0 }; function rootReducer(state = initialState, action) { switch (action.type) { case 'INCREMENT': return { value: state.value + 1 }; case 'DECREMENT': return { value: state.value - 1 }; default: return state; } } const store = createStore(rootReducer); console.log(store.getState()); `}
combineReducers
The combineReducers
function is used to combine multiple reducers into one.
{` import { combineReducers, createStore } from 'redux'; function userReducer(state = {}, action) { switch (action.type) { case 'SET_USER': return action.payload; default: return state; } } function postsReducer(state = [], action) { switch (action.type) { case 'ADD_POST': return [...state, action.payload]; default: return state; } } const rootReducer = combineReducers({ user: userReducer, posts: postsReducer }); const store = createStore(rootReducer); console.log(store.getState()); `}
applyMiddleware
The applyMiddleware
function is used to enhance the store with middleware.
{` import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; const logger = store => next => action => { console.log('dispatching', action); let result = next(action); console.log('next state', store.getState()); return result; }; const rootReducer = (state = {}, action) => state; const store = createStore(rootReducer, applyMiddleware(logger, thunk)); `}
Application Example
Below is an example of a simple React application using Redux to manage state:
{` // index.js import React from 'react'; import ReactDOM from 'react-dom'; import { createStore } from 'redux'; import { Provider } from 'react-redux'; import App from './App'; import rootReducer from './reducers'; const store = createStore(rootReducer); ReactDOM.render(, document.getElementById('root') ); // reducers/index.js import { combineReducers } from 'redux'; const counter = (state = 0, action) => { switch (action.type) { case 'INCREMENT': return state + 1; case 'DECREMENT': return state - 1; default: return state; } }; export default combineReducers({ counter }); // App.js import React from 'react'; import { useSelector, useDispatch } from 'react-redux'; function App() { const count = useSelector(state => state.counter); const dispatch = useDispatch(); return ( ); } export default App; `}Counter: {count}
Hash: 080baa17c90b5e97f32d94164cb0ec3f1729753654e21295166499bb454b88c8