Redux Basics Cheat Sheet 📖
Tags: javascript, redux, webdev, beginners
Published: 2021-04-06 12:22:39

#Basics
*scheme*
![scheme](https://res.cloudinary.com/danilnotorious/image/upload/v1617708751/Screenshot_2020-08-11_at_4.45.11_PM_llg0p2.png)

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).
```javascript
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" });
```
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.
```javascript
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" });
```
Counter example:
```javascript
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);
```
Together with the type of action in reduce through action, you can also transfer additional information to perform this very action:
```javascript
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);
```

## Simplifying your code: Action Creator & bindActionCreators
### Action Creator
Action Creator is a separate function that creates action objects, making it easy to write code:
```javascript
const inc = () => ({ type: "INC" });
const dec = () => ({ type: "DEC" });
const rnd = (payload) => ({ type: "RND", payload });
```
### bindActionCreators
bindActionCreator is binds any accepted actionCreator to dispatch:
```javascript
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);
```
Redux has its own `bindActionCreators` function:
```javascript
import { createStore, bindActionCreators } from "redux";

const incDispatch = bindActionCreator(inc, dispatch);
const decDispatch = bindActionCreator(dec, dispatch);
const rndDispatch = bindActionCreator(rnd, dispatch);
```
The difference from a self-written function is that `bindActionCreators` can take an object of a set of actions as the first argument:
```javascript
const { incDispatch, decDispatch, rndDispatch } = bindActionCreators(
  {
    incDispatch: inc,
    decDispatch: dec,
    rndDispatch: rnd,
  },
  dispatch
);
```
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:
```javascript
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);
});
```
---
Thanks for reading! ❤️ 
You can also check out my [JavaScript Basic Type Conversions Cheat Sheet](https://dev.to/danielkrupnyy/javascript-basic-type-conversion-cheat-sheet-1gg4)
If you have something to add, please, describe in the comments 👇🏻