Redux Basics Cheat Sheet 📖

danielkrupnyy

Daniel Krupnyy

Posted on April 6, 2021

Redux Basics Cheat Sheet 📖

Basics

scheme
scheme

All components states are stored in the global state. Components can read information from it, but cannot directly change something in it.
To change the global state, components create Actions objects and submit them to the Redux Store. Such operations are called dispatches.
The Redux Store in turn uses the Reducer function to update the state.


Reducer

This is a function that is used to store logic. Accepts state and action (simple object).

const reducer = (state = 0, action) => {
  switch (action.type) {
    case "INC":
      return state + 1;
    default:
      return state;
  }
};

let state = reducer(undefined, {});

state = reducer(state, { type: "INC" });
Enter fullscreen mode Exit fullscreen mode

If state is undefined, then you need to return the original initialState.
If the action type is unknown, then you need to return state unchanged.

Reducer must be a pure function! This means that:

  1. The return value depends only on the arguments (you can only work with arguments)
  2. The function has no side effects (changing external data or changing arguments)

Redux Store

The redux store's job is to coordinate data in a react app.

import { createStore } from "redux";

const reducer = (state = 0, action) => {
  switch (action.type) {
    case "INC":
      return state + 1;
    default:
      return state;
  }
};

// Creating store (by default — 0)
const store = createStore(reducer);

// Subscriptions on changes in store 
store.subscribe(() => [console.log(`store changed: ${store.getState()}`)]);

// Handling new actions
store.dispatch({ type: "INC" });
store.dispatch({ type: "INC" });
Enter fullscreen mode Exit fullscreen mode

Counter example:

import { createStore } from "redux";

const reducer = (state = 0, action) => {
  switch (action.type) {
    case "INC":
      return state + 1;
    case "DEC":
      return state - 1;
    default:
      return state;
  }
};

const store = createStore(reducer);

const dec = document.getElementById("dec");
const inc = document.getElementById("inc");

dec.addEventListener("click", () => store.dispatch({ type: "DEC" }));
inc.addEventListener("click", () => store.dispatch({ type: "INC" }));

const update = () => {
  const counter = document.getElementById("counter");
  counter.textContent = store.getState();
};

store.subscribe(update);
Enter fullscreen mode Exit fullscreen mode

Together with the type of action in reduce through action, you can also transfer additional information to perform this very action:

import { createStore } from "redux";

const reducer = (state = 0, action) => {
  const { type, payload } = action;

  switch (type) {
    case "INC":
      return state + 1;
    case "DEC":
      return state - 1;
    case "RND":
      return state + payload;
    default:
      return state;
  }
};

const store = createStore(reducer);

const dec = document.getElementById("dec");
const inc = document.getElementById("inc");
const rnd = document.getElementById("rnd");

dec.addEventListener("click", () => store.dispatch({ type: "DEC" }));
inc.addEventListener("click", () => store.dispatch({ type: "INC" }));

// ---
rnd.addEventListener("click", () => {
  const payload = Math.floor(Math.random() * 10 + 1);
  store.dispatch({ type: "RND", payload });
});
// ---

const update = () => {
  const counter = document.getElementById("counter");
  counter.textContent = store.getState();
};

store.subscribe(update);
Enter fullscreen mode Exit fullscreen mode

Simplifying your code: Action Creator & bindActionCreators

Action Creator

Action Creator is a separate function that creates action objects, making it easy to write code:

const inc = () => ({ type: "INC" });
const dec = () => ({ type: "DEC" });
const rnd = (payload) => ({ type: "RND", payload });
Enter fullscreen mode Exit fullscreen mode

bindActionCreators

bindActionCreator is binds any accepted actionCreator to dispatch:

const store = createStore(reducer);
const { dispatch } = store;

const incDispatch = () => dispatch(inc());
const decDispatch = () => dispatch(dec());
const rndDispatch = (payload) => dispatch(rnd(payload));

// bindActionCreator working like that
const bindActionCreator = (creator, dispatch) => (...args) => {
  dispatch(creator(...args));
};

// Code is shorter now
const incDispatch = bindActionCreator(inc, dispatch);
const decDispatch = bindActionCreator(dec, dispatch);
const rndDispatch = bindActionCreator(rnd, dispatch);
Enter fullscreen mode Exit fullscreen mode

Redux has its own bindActionCreators function:

import { createStore, bindActionCreators } from "redux";

const incDispatch = bindActionCreator(inc, dispatch);
const decDispatch = bindActionCreator(dec, dispatch);
const rndDispatch = bindActionCreator(rnd, dispatch);
Enter fullscreen mode Exit fullscreen mode

The difference from a self-written function is that bindActionCreators can take an object of a set of actions as the first argument:

const { incDispatch, decDispatch, rndDispatch } = bindActionCreators(
  {
    incDispatch: inc,
    decDispatch: dec,
    rndDispatch: rnd,
  },
  dispatch
);
Enter fullscreen mode Exit fullscreen mode

The keys of such an object will be the names of the functions that we want to receive. In the case of a set of actions, bindActionCreators returns an object with ready-made functions that can be destructed:

import { createStore, bindActionCreators } from "redux";
import reducer from "./reducer";
import * as actions from "./actions"; // Import all actions in object format

const update = () => {
  const counter = document.getElementById("counter");
  counter.textContent = store.getState();
};

const store = createStore(reducer);
const { dispatch } = store;

const { inc, dec, rnd } = bindActionCreators(actions, dispatch);

store.subscribe(update);

document.getElementById("inc").addEventListener("click", inc);
document.getElementById("dec").addEventListener("click", dec);
document.getElementById("rnd").addEventListener("click", () => {
  const payload = Math.floor(Math.random() * 10);
  rnd(payload);
});
Enter fullscreen mode Exit fullscreen mode

Thanks for reading! ❤️
You can also check out my JavaScript Basic Type Conversions Cheat Sheet
If you have something to add, please, describe in the comments 👇🏻

💖 💪 🙅 🚩
danielkrupnyy
Daniel Krupnyy

Posted on April 6, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Redux for beginners
javascript Redux for beginners

April 30, 2023

Building a Login System using Redux
javascript Building a Login System using Redux

October 26, 2022

Redux Basics Cheat Sheet 📖
javascript Redux Basics Cheat Sheet 📖

April 6, 2021