Skip to content

Redux

November 22, 2023
December 4, 2015

Redux = **_Red_**ucer + Fl**_ux_**

I'm using Atomic state manager instead of Redux
use old materials for the concepts rather than the syntax

Redux by Dan Abramov (gaearon) implements Flux Store in a FP way. This enables a lot of interesting tools, including time travel with app state. He committed the topic to a conference and Redux came out of the demo code. It is now part of the official React project.

Redux Doc
reduxjs/redux: Predictable state container for JavaScript apps
Ecosystem | Redux

Redux Toolkit
A Guide To Redux Toolkit With TypeScript — Smashing Magazine

The official, opinionated, batteries-included toolset for efficient Redux development.
It also removed most of the need for Redux middlewares (redux-thunk, redux-saga, ...) and boilerplates.

The only introduction to Redux (and React-Redux) you’ll ever need
xgrommx/awesome-redux
markerikson/react-redux-links: Curated tutorial and resource links I've collected on React, Redux, ES6, and more

React.js Conf 2016 - Lin Clark - A Cartoon Guide to the Wilds of Data Handling - YouTube

React Redux Tutorial for Beginners [2019] - RWieruch !important
How Redux Works: A Counter-Example
Understanding Redux: The World’s Easiest Guide to Beginning Redux

Practical Redux · Mark's Dev Blog
Idiomatic Redux · Mark's Dev Blog

Understanding Redux: Beginner's guide to modern state management
Redux Basics Explained From A Beginner's Perspective - DEV Community 👩‍💻👨‍💻
Leveling Up with React: Redux | CSS-Tricks
Blogged Answers: Resources for Learning Redux · Mark's Dev Blog
Practical Redux · Mark's Dev Blog
Idiomatic Redux: The Tao of Redux, Part 1 - Implementation and Intent · Mark's Dev Blog
Idiomatic Redux: The Tao of Redux, Part 2 - Practice and Philosophy · Mark's Dev Blog

Redux: The Under The Hood Tour - DEV Community 👩‍💻👨‍💻 !important, internals

Action and ActionCreator

Idiomatic Redux: Why use action creators? · Mark's Dev Blog

// Action
{ type: 'ADD_TODO', payload: 'Use Redux' }

// ActionCreator
addTodo = (text) => {
  return { type: 'ADD_TODO', payload: text };
}

// thunk, return function/promise for `dispatch()`
// avoid accessing state other than conditional dispatch
// (using cached data, checking authentication)
// passing data in store is considered an anti-pattern
// OR perform any side effect (fat action)
export function addTodoWithCheck(text) {
  return (dispatch, getState) => {
    if (getState().todos.length === 3) {
      // early exit
      return;
    }

    dispatch(addTodo(text));
  }
}

Reducer

reducer = (state, action) => {
  return newState;
};

// reducing boilerplate with `createReducer()` and state slicing
function createReducer(initialState, handlers) {
  return function reducer(state = initialState, action) {
    if (handlers.hasOwnProperty(action.type)) {
      return handlers[action.type](state, action);
    } else {
      return state;
    }
  };
}

const visibilityReducer = createReducer("SHOW_ALL", {
  SET_VISIBILITY_FILTER: (visibilityState, action) => action.visibility,
});

const todosReducer = createReducer([], {
  // case handlers
  ADD_TODO: addTodo,
  TOGGLE_TODO: toggleTodo,
  EDIT_TODO: editTodo,
});

const appReducer = combineReducers({
  visibilityFilter: visibilityReducer,
  todos: todosReducer,
});

Reusing Reducer Logic · Redux by bounding different name to it for different components and state slice
Understanding How Reducers are Used in Redux | CSS-Tricks

Middleware

Redux middleware is designed by creating functions that can be composed together before the main dispatch method is invoked.

Understanding Redux Middleware - Mark - Medium
Methods for tracking action status in Redux - LogRocket Blog type.endsWith("_REQUEST|SUCCESS|FAILURE") to set state

(storeInstance) =>
  (functionToCallWithAnActionThatWillSendItToTheNextMiddleware) =>
  (actionThatDispatchWasCalledWith) =>
    valueToUseAsTheReturnValueOfTheDispatchCall;
// or in short
(store) => (next) => (action) => result;

// redux-thunk
const middledWare =
  ({ dispatch, getState }) =>
  (next) =>
  (action) => {
    if (typeof action === "function") {
      return action(dispatch, getState, extraArgument);
    }
    return next(action);
  };
const middlewares = applyMiddleware(middleware1, middleware2);
const store = createStore(reducers, initialState, middlewares);
export function loadPosts(userId) {
  return {
    // Types of actions to emit before and after
    types: ["LOAD_POSTS_REQUEST", "LOAD_POSTS_SUCCESS", "LOAD_POSTS_FAILURE"],
    // Check the cache (optional):
    shouldCallAPI: (state) => !state.posts[userId],
    // Perform the fetching:
    callAPI: () => fetch(`http://myapi.com/users/${userId}/posts`),
    // Arguments to inject in begin/end actions
    payload: { userId },
  };
}

function callAPIMiddleware({ dispatch, getState }) {
  return (next) => (action) => {
    const {
      types,
      callAPI,
      shouldCallAPI = (state) => true,
      payload = {},
    } = action;

    if (!types) {
      // Normal action: pass it on
      return next(action);
    }

    if (!shouldCallAPI(getState())) {
      return;
    }

    const [requestType, successType, failureType] = types;

    dispatch(
      Object.assign({}, payload, {
        type: requestType,
      }),
    );

    return callAPI().then(
      (response) =>
        dispatch(
          Object.assign({}, payload, {
            response,
            type: successType,
          }),
        ),
      (error) =>
        dispatch(
          Object.assign({}, payload, {
            error,
            type: failureType,
          }),
        ),
    );
  };
}

Store

import { combineReducers, createStore, applyMiddleware } from "redux";

rootReducer = combineReducers({ key1: reducer1, key2: reducer2 });
store = createStore(rootReducer, initState, applyMiddleware(middlewares));

The Ultimate Cheat Sheet on Splitting Dynamic Redux Reducers

Enhancers

Enhancers return a new enhanced version of createStore(). applyMiddleware() is (actually it returns) an enhancer.

const ourAwesomeEnhancer =
  (createStore) => (reducer, initialState, enhancer) => {
    const store = createStore(monitoredReducer, initialState, enhancer);
    //  add enhancer logic

    return {
      ...store,
      //   you can override the some store properties or add new ones
    };
  };

#187: Redux, React, and Functional JavaScript with Dan Abramov - The Changelog
JSJ The Evolution of Flux Libraries with Andrew Clark and Dan Abramov
Dan Abramov - Live React: Hot Reloading with Time Travel at react-europe 2015 - YouTube The presentation where Redux is born
Dan Abramov - The Redux Journey at react-europe 2016 - YouTube

Idiomatic Redux · Mark's Dev Blog
Idiomatic Redux: The Tao of Redux, Part 1 - Implementation and Intent · Mark's Dev Blog
Idiomatic Redux: The Tao of Redux, Part 2 - Practice and Philosophy · Mark's Dev Blog
Idiomatic Redux: The History and Implementation of React-Redux · Mark's Dev Blog

SurviveJS - Webpack and React - Redux - Reinventing Flux - Interview with Dan Abramov
A cartoon intro to Redux — Code Cartoons — Medium Redux vs Flux
Understanding the Redux paradigm | Tryolabs | Blog

Screencast

Fundamentals of Redux Course from Dan Abramov | egghead.io free video course, !important
tayiorbeii/egghead.io_redux_course_notes: Notes (and partial transcription) of Dan Abramov's Redux course videos on http://egghead.io
Building React Applications with Idiomatic Redux | egghead.io free video course, !important

Learn Redux — 20 video tutorials to help you learn how to build JavaScript apps with React.js and Redux. !important, by Wes Bos
Learn Redux - YouTube by Wes Bos

17. React Redux with Dan Abramov - YouTube
Live-editing React app without refresh on Vimeo

Ecosystem

xgrommx/awesome-redux: Awesome list of Redux examples and middlewares
markerikson/redux-ecosystem-links: A categorized list of Redux-related addons, libraries, and utilities
Understanding Redux Middleware – Medium

pauldijou/redux-act: An opinionated lib to create actions and reducers for Redux

gaearon (Dan Abramov)
paularmstrong/normalizr: Normalizes nested JSON according to a schema normalize domain data

reduxjs/redux-devtools: DevTools for Redux with hot reloading, action replay, and customizable UI uses normalizr and make observations on Flux
Redux Devtools for Dummies – codeburst
troch/reinspect: Use redux devtools to inspect useState and useReducer

gajus/redux-immutable: redux-immutable is used to create an equivalent function of Redux combineReducers that works with Immutable.js state.

omnidan/redux-undo: higher order reducer to add undo/redo functionality to redux state containers

Redux Utilities
redux-utilities/flux-standard-action: A human-friendly standard for Flux action objects.
redux-utilities/redux-promise: FSA-compliant promise middleware for Redux.
redux-utilities/redux-actions: Flux Standard Action utilities for Redux.
redux-utilities/reduce-reducers: Reduce multiple reducers into a single reducer from left to right

acdlite/recompose: A React utility belt for function components and higher-order components. ideas incorporated into React Hooks

leoasis/redux-immutable-state-invariant: Redux middleware that detects mutations between and outside redux dispatches. For development use only.
socialtables/redux-unhandled-action: Redux middleware that logs an error to the console when an action is fired and the state is not mutated

On the contrary

flux-alternatives

Blogged Answers: Why React Context is Not a "State Management" Tool (and Why It Doesn't Replace Redux) · Mark's Dev Blog
Blogged Answers: Redux - Not Dead Yet! · Mark's Dev Blog
When (and when not) to reach for Redux |> Changelog

You Might Not Need Redux – Medium
Redux feels bloated, complicated and not easy. What are the alternative? : reactjs
reactjs - What could be the downsides of using Redux instead of Flux - Stack Overflow
Redux isn’t dead - LogRocket Blog

Introduction - Reatom — state manager with a focus of all needs
artalar/reatom: State manager with a focus of all needs

Tips and Tricks

Two Weird Tricks with Redux
Scaling Redux for real-life applications – Hacker Noon
Scaling your Redux App with ducks
Redux Patterns and Anti-Patterns - Affirm Tech Blog
Optimize Redux before it kills your Application - JavaScript in Plain English - Medium

Hooks API

Redux Toolkit
RTK Query Overview | Redux Toolkit
reduxjs/redux-toolkit: The official, opinionated, batteries-included toolset for efficient Redux development

Presentations: Modern Redux with Redux Toolkit · Mark's Dev Blog
Redux Toolkit - The Standard Way to Write Redux - DEV Community
Redux toolkit crash course. Everything you need to know. #reactjs #redux - YouTube
Redux Toolkit Tutorial – JavaScript State Management Library - YouTube

Hooks · React Redux
How To Use Redux with React Hooks - ITNEXT
How I reduced the code in my Redux app by using Redux Hooks.

Data flow

Handles async and side effects:
reduxjs/redux-thunk: Thunk middleware for Redux
redux-saga/redux-saga: An alternative side effect model for Redux apps uses while-loop and generators
How to perfectly handle user-interactions with redux-saga
redux-loop/redux-loop: A library that ports Elm's effect system to Redux
lelandrichardson/redux-pack: Sensible promise handling and middleware for redux

Redux pattern: byId reducer - NEXT Engineering - Medium
Async actions handling with redux-thunk - NaNLABS
What the heck is a 'thunk'?
Thunks in Redux: The Basics - Fullstack Academy - Medium
javascript - How to dispatch a Redux action with a timeout? - Stack Overflow
Where do I put my business logic in a React Redux application? | CodeWinds
Handling Asynchronous Actions in Redux - Better Programming - Medium
Don’t use async Redux middleware - Christian Chown - Medium
Handling Asynchronous Actions with Redux Thunk - The Startup - Medium

A chained modals example w/ React Bootstrap - SaltyCrane Blog
A chained modals example w/ React Router (part 2) - SaltyCrane Blog
Comparing vanilla React, Redux, and Redux Thunk - Chained modals exercise part 3 - SaltyCrane Blog

Actors: How to dispatch actions after Redux state changes
Can I dispatch multiple actions from Redux action creators?
Updating Normalized Data · Redux

christianalfoni - The case for function tree
Redux 4 Ways – React Native Training – Medium
State Management with Redux
Querying a Redux Store – Medium
Idiomatic Redux: Thoughts on Thunks, Sagas, Abstraction, and Reusability · Mark's Dev Blog
You may not need to thunk – Medium
Using redux-saga To Simplify Your Growing React Native Codebase
react-redux-links/redux-side-effects.md at master · markerikson/react-redux-links

Cheng Lou - On the Spectrum of Abstraction at react-europe 2016 - YouTube !important

Derived Data

Deriving Data with Selectors | Redux
Selector pattern in React/Redux apps
Understanding Javascript Selectors With and Without Reselect
React, Reselect and Redux - Dan Parker - Medium

reduxjs/reselect: Selector library for Reduxmemoized transform
heyimalex/reselect-map: Selectors for mapping over collections the transform is expensive for each item
Mastercard Developers

import { createSelector } from 'reselect'

// signature matches the invocation from `mapStateToProps()`
const inputSelector1 = (state, props) => state[props.key1]
const inputSelector2 = (state, props) => state.key2

const mySelector = createSelector(
  inputSelector1, inputSelector2...,
  (input1, input2...) => {
    return ...
  }
)

// check this if the component using `mySelector()` have multiple instances
// https://redux.js.org/recipes/computing-derived-data#sharing-selectors-across-multiple-components