- Redux - Home
- Redux - Overview
- Redux - Installation
- Redux - Core Concepts
- Redux - Data Flow
- Redux - Store
- Redux - Actions
- Redux - Pure Functions
- Redux - Reducers
- Redux - Middleware
- Redux - Devtools
- Redux - Testing
- Redux - Integrate React
- Redux - React Example
- Redux Useful Resources
- Redux - Quick Guide
- Redux - Useful Resources
- Redux - Discussion
Redux Cheatsheet
This Redux cheatsheet offers a concise reference to essential Redux concepts, including store creation, actions, reducers, and middleware. It covers advanced topics such as integrating Redux with React, handling async actions, and using the Redux Toolkit, with practical code examples for each feature. Designed for both beginners and experienced developers, this guide helps you quickly understand Redux's state management principles and its interaction with React.
Table of Contents
- Introduction to Redux
- Creating a Store
- Using a Store
- React Redux Integration
- Mapping State and Dispatch
- Combining Reducers
- Middleware
- Actions
- Reducers
- Redux Toolkit
- Async Actions
- Action Creators
- Selectors
- React-Redux Hooks
- Redux DevTools
- Testing
- TypeScript in Redux
- Redux React
- Immutable State Management in Redux
Introduction to Redux
Redux is a predictable state container for JavaScript apps, it is most commonly used together with React. It enables you to address all of your applications global state needs by providing a single store where actions and reducers control the state. Redux aids in an application by making its state more predictable, easier to test, and easier to debug.
Creating a Store
Initializes a Redux store using createStore(), defining an initial state and a reducer function to manage state updates.
Example:
import { createStore } from 'redux';
const initialState = { value: 0 };
function counterReducer(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(counterReducer);
Using a Store
Interacts with the store using methods like dispatch() to send actions, getState() to retrieve the current state, and subscribe() to listen for state changes.
Store Methods:
| Method | Description |
| store.dispatch() | Dispatches an action to update the state. |
| store.getState() | Retrieves the current state. |
| store.subscribe() | Registers a listener to state changes. |
Example:
store.dispatch({ type: 'INCREMENT' });
console.log(store.getState()); // { value: 1 }
store.subscribe(() => {
console.log('State changed:', store.getState());
});
React Redux Integration
Provider Component: The <Provider> component makes the Redux store available to React components.
Example:
import { Provider } from 'react-redux';
<Provider store={store}>
<App />
</Provider>
Mapping State and Dispatch
Mapping State to Props: Maps the Redux state to component props.
Mapping Dispatch to Props: Maps dispatchable actions to props.
Example:
import { connect } from 'react-redux';
function App({ message, onMessageClick }) {
return (
<div onClick={() => onMessageClick('Hello')}>{message}</div>
);
}
const mapStateToProps = (state) => ({
message: state.message
});
const mapDispatchToProps = (dispatch) => ({
onMessageClick: (msg) => dispatch({ type: 'MESSAGE_CLICK', message: msg })
});
export default connect(mapStateToProps, mapDispatchToProps)(App);
Combining Reducers
Combining combineReducers() to merge multiple reducers into a single root reducer makes state management modular.
Example:
import { combineReducers } from 'redux';
const rootReducer = combineReducers({
counter: counterReducer,
user: userReducer
});
const store = createStore(rootReducer);
Middleware
Middleware enhances Redux by adding custom logic between dispatching actions and updating the state, such as logging or handling async operations.
Example :
const logger = (store) => (next) => (action) => {
console.log('Dispatching:', action);
const result = next(action);
console.log('Next state:', store.getState());
return result;
};
Applying Middleware: Use applyMiddleware() to add middleware to the Redux store.
Example:
import { applyMiddleware, createStore } from 'redux';
const enhancer = applyMiddleware(logger);
const store = createStore(counterReducer, enhancer);
Actions
Actions are plain JavaScript objects that describe a state change in Redux, containing a type property and optional payload.
| Feature | Description | Code Example |
| Defining an Action | Actions are plain objects with a type property. |
const increment = { type: 'INCREMENT' }; |
|
Action Creator |
Functions that return action objects. |
function increment() { return { type: 'INCREMENT' }; } |
|
Action with Payload |
Actions can include a payload to pass additional data. |
function addTodo(text) { return { type: 'ADD_TODO', payload: text }; } |
|
Dispatching an Action |
Use dispatch to send an action to the store. |
dispatch(increment()); |
Reducers
Reducers are pure functions that take the current state and an action, then return a new state based on the action type.
| Feature | Description | Code Example |
| Writing a Reducer |
A reducer is a pure function that returns the new state based on the action type. |
function counterReducer(state = 0, action) { switch (action.type) { |
|
Handling Multiple Actions |
Reducers handle multiple action types by using switch or if statements. |
function counterReducer(state = 0, action) { if (action.type === 'INCREMENT') return state + 1; |
Redux Toolkit
Simplifies Redux setup with built-in utilities like configureStore and createSlice.
| Feature | Description | Code Example |
| configureStore | A function to create the Redux store with automatic middleware setup. |
import { configureStore } from '@reduxjs/toolkit'; |
|
createSlice |
Automatically generates action creators and reducers based on a slice of state. |
const counterSlice = createSlice({ |
|
createAsyncThunk |
Simplifies the creation of async actions. |
const fetchData = createAsyncThunk('data/fetch', async () => { |
Async Actions
Explains handling asynchronous operations like API calls using middleware such as redux-thunk or redux-saga.
| Middleware | Description | Code Example |
| redux-thunk | A middleware to handle asynchronous actions. |
const fetchData = () => dispatch => { |
|
redux-saga |
A middleware that handles async operations using generators. |
function* fetchDataSaga() { |
Selectors
Selectors cover functions that retrieve and optimize access to specific pieces of Redux state.
| Feature | Description | Code Example |
| Basic Selector | A function that retrieves data from the store. |
const selectCount = state => state.counter; |
|
Reselect Selector |
A memoized selector that computes derived data. |
import { createSelector } from 'reselect'; |
|
Using Selectors in Components |
Using useSelector hook to access state in React components. |
import { useSelector } from 'react-redux'; |
Action Creators
Simple Action Creator: A function that returns an action object, making it reusable and reducing repetition in Redux applications.
const addToDo = (text) => ({ type: 'TODO_ADDED', payload: text });
store.dispatch(addToDo('Learn Redux'));
Asynchronous Action Creators: Functions that dispatch multiple actions, such as starting an API request and handling success or failure responses.
const fetchData = () => {
return async (dispatch) => {
dispatch({ type: 'FETCH_REQUEST' });
const data = await apiCall();
dispatch({ type: 'FETCH_SUCCESS', payload: data });
};
}
Using bindActionCreators:
import { bindActionCreators } from 'redux';
const boundAddToDo = bindActionCreators(addToDo, store.dispatch);
boundAddToDo('Learn Redux');
React-Redux Hooks
Shows how to use react hooks like useSelector and useDispatch to interact with Redux in functional components.
| Concept | Code Example |
| Using useSelector |
const count = useSelector((state) => state.counter.count); |
|
Using useDispatch |
const dispatch = useDispatch(); |
|
Dispatching Action |
dispatch(addCount()); |
|
Using useSelector with Multiple Values |
const count = useSelector((state) => state.counter.count); |
|
Shallow Equality with useSelector |
const { count, user } = useSelector((state) => ({ |
|
Old connect Version |
import { connect } from 'react-redux'; |
|
New useSelector + useDispatch |
import { useDispatch, useSelector } from 'react-redux'; |
Redux DevTools
Redux DevTools describes how to debug Redux applications with state inspection and time-travel debugging.
| Feature | Description | Usage |
| Install | Add DevTools to browser for debugging. |
npm install --save-dev devtools-extension |
|
Setup Store |
Integrate DevTools in Redux store. |
composeWithDevTools() in createStore() |
| Trace Actions | View action call stack. |
trace: true, traceLimit: 25 |
|
Skip Actions |
Remove specific actions from timeline. |
Use "Log Monitor" or "Inspector" in UI. |
|
Jump to State |
Navigate between states. |
Use "Inspector" in DevTools. |
|
Dispatch |
Manually test actions. |
Use "Dispatch" tab in DevTools. |
|
Filter Actions |
Allow/block actions in timeline. |
actionsBlacklist: 'ACTION_TYPE' |
| Persist State | Retain state across reloads. | Click "Persist" or use ?debug_session= |
| Lock State | Freeze current state. | Click "Lock" in DevTools. |
| Time Travel | Replay state history. | Use timeline controls in DevTools. |
Testing
Explains testing Redux reducers, actions, and store behavior using assertions.
| Component | Code |
|
Test Reducer |
expect(reducer(state, action)).toEqual(expectedState) |
|
Test Action |
expect(actionCreator(payload)).toEqual(expectedAction) |
|
Dispatch Action |
store.dispatch(action(payload)) |
|
Assert State |
expect(store.getState().key).toEqual(value) |
TypeScript in Redux
Covers using TypeScript with Redux for better type safety and maintainability.
// Setup Store
import { configureStore } from '@reduxjs/toolkit';
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});
export type RootState = ReturnType<typeof store.getstate="">;
export type AppDispatch = typeof store.dispatch;
// Typed Hooks
import { useDispatch, useSelector } from 'react-redux';
export const useAppDispatch: () => AppDispatch = useDispatch;
export const useAppSelector: (state: RootState) => any = useSelector;
// Slice Example
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface CounterState {
value: number;
}
const initialState: CounterState = { value: 0 };
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
// Thunk Example
import { AppThunk } from './store';
export const fetchCounter = (): AppThunk => async (dispatch) => {
const data = await fetch('/api/counter').then((res) => res.json());
dispatch(incrementByAmount(data.value));
};
// Usage in Component
import React from 'react';
import { useAppSelector, useAppDispatch } from './hooks';
import { increment } from './counterSlice';
const Counter = () => {
const count = useAppSelector((state) => state.counter.value);
const dispatch = useAppDispatch();
return (
<div>
<button onclick="{()" ==""> dispatch(increment())}>Increment</button>
<p>{count}</p>
</div>
);
};
Redux-React
Redux-React tells how Redux is used in React applications to manage the global state.
| Component | Explanation | Code |
| Store | Creates Redux store. | const store = createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__()); |
| Provider | Links store to React. | <Provider store={store}><App /></Provider> |
| mapStateToProps | Maps state to props. | const mapStateToProps = (state) => ({ counter: state }); |
| mapDispatchToProps | Maps actions to props. | const mapDispatchToProps = (dispatch) => ({ increment: () => dispatch(increment()) }); |
| connect | Connects component to store. | export default connect(mapStateToProps, mapDispatchToProps)(Counter); |
| Actions | Redux actions. | export const increment = () => ({ type: 'INCREMENT' }); |
| Reducer | Updates state. |
const reducer = (state = 0, action) => { switch(action.type) { case 'INCREMENT': return state + 1; } }; |
| Component | Triggers Redux actions. | <button onClick={increment}>INCREMENT</button> |
Immutable State Management in Redux
Emphasizes the importance of keeping the Redux state immutable to prevent unintended mutations.
| Tools | Example Code |
| Return New State |
return { ...state, counter: state.counter + 1 }; |
|
Spread Operator |
todos: [...state.todos, action.payload] |
|
Use Libraries |
import produce from "immer"; |
|
Nested Update |
return { ...state, nested: { ...state.nested, key: 'value' } }; |