Everything You Need to Know About Redux

Brandon S. Ha
8 min readAug 16, 2021

--

It’s a series of Redux. Hope you go through everything as Redux is not easy concept to understand if you are beginner and i am still beginner too but i have written this series to share my knowledge.

study order

  1. basic redux — understand what Redux is
  2. Try todo list with vanilla Redux
  3. React-redux with hooks(useSelector, useDispatch)
  4. Redux middlewares such as Redux Thunk & Redux Saga
  5. Redux toolkit(RTK)
  6. Redux toolkit Query

Why Redux?

Before you learn redux, you need to know what is Redux & why its used for.

Simply, 2 reasons.

  1. To avoid props drilling. In react, you pass state through so many props.
  2. To ease state management.

Introducing MVC architecture

MVC

MVC is a design pattern. The client sends the request to the controller > update the model according to the action > pass it to the view

When an action comes in, the controller receives and then update the data held by the model. After that, the changes are reflected in the view.

However, as the application gets bigger and bigger, its hard to figure out which model and view are intertwined.

The reason why we apply Flux over MVC?
Facebook had reported the cause of the alarm bug in the message app with two-way data flow. So to fix it, introduced Flux with one-way data flow.

What is Flux?

Flex is kind of abstract concept. To overcome MVC limitation, Facebook created an application architecture.

What is Redux?

It’s a JS library that implement the flux architecture created by Facebook. A state management system for cross components or app-wide state.

Usage : Efficient data flow and state management between components

One thing to keep in mind

In order to update values immutably, your code must copy the existing objects as Redux expects that all state updates are immutably.

dispatch an action and that action trigger a reducer

Core redux concept

* Redux uses a “one-way data flow” app structure

When something happens in the app:

The UI dispatches an action.

The store runs the reducers, and the state is updated based on what occurred.

The store notifies the UI that the state has changed.

The UI re-renders based on the new state.

Redux Terms and Concepts

Action
An action is a plan JS object with type filed. It always has a type. The rest is payload.

const addTodoAction = {
type: 'todos/todoAdded',
payload: 'buy milk' // additional info
}

Action creators
A function that creates and return an action object

Reducers
A reducer is a function that receives the current state and an action object. To decide how to update the state and return the new state:

function counterReducer(state = initialState, action) {// Check to see if the reducer cares about this actionif (action.type === 'counter/increment') {// If so, make a copy of `state`return {...state,// and update the copy with the new valuevalue: state.value + 1}}

store

The current Redux state lives in store. The store is created by passing in a reducer.

const store = createStore((reducer, [preloadedState], [enhancer]))

No need to get confused with creteStore and ConfigureStore. RTK provide configureStore()that wrap createStore()

dispatch

The only way to update the state in redux store is call “store.dispatch()” and pass in an action object

store.dispatch({type: 'counter/increment'})

Example : story

You are at Domino Pizza shop! Hmm yummy! Customers are about to order a pizza with different toppings. All teams from management, chef, front cashier are need to know about that order data. Those data is stored in a central repository so it can be updated easily.

{
Type : "ORDER_PIZZA",
payload : {
Name: "Marie",
Amount: "$30"
}}

3 Action types : Put an order, Make a pizza or Cancel the order

Redux cycle(Pizza store)

Action Creator -> Action -> dispatch -> Reducers -> State

Customer order -> Pizza -> Machine -> Departments -> All order status data.

Redux Cycle

  1. create a store
import { createStore } from "redux";

you can have only one store to manage the data.

2. dispatch the action

Action is like what we want to do. Dispatch method send actions to the store.
Actions (objects) MUST have TYPE property — what kind of action.
Don’t mutate the state — redux built on Immutability (copy)

store.dispatch({ type: "ADD_TODO", text: toDo });

2. Handle a reducer & connect it
Update the new state. Reducer is like a function that used to update store and have 2 arguments which are (state, action).

  • state — old state/state before update
  • action — What happened/ what update

Here’s what a simple Reducer looks like:

function reducer(state, action) {
//return new state
}

To handle several action cases, we typically use switch statement below. By using a switch statement, you can handle different action types within your Reducer.

4. subscribe

store.subscribe(paintTodos);

You never mutate the state. but the only way to modify is to dispatch the action. Keep it mind that return new state objects, instead of mutating the previous state.

never do like state.push(action.text),

Do this by creating a new array

return […state, {text: action.text}]

The reason why we use filter() is that we should never ever mutate the array.
filter() method creates a new array with all elements.

React-redux

The folder structure

reducer, actionsand store

Using React-redux, it provides Provider & Connect().

/actions -> Contains files to related to action creators
/components -> Files related to components
/reducers -> Files related to reducers
/index.js -> set up both react and redux.

Reducer is a pure function that changes the state. Whenever dispatch() method run, state re-updated. To handle these several reducers, we use combineReducers() of Redux package.

To create a store, we use createStore() method. Store provide state down to child component(<App/>) with Provider. subscribe() and dispatch() methods will be there to notice the changes.

const render = () => {  
ReactDOM.render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root')
)
};

Redux Middleware

It was the most difficult part to understand for me. The flow is the same as we’ve studied. but its adding an extra step which handle API call. Since reducer is pure function, create a new state only.

Async logic and data fetching with Redux middleware

Redux-Thunk

A thunk is a specific kind of Redux function that can contain asynchronous logic. Thunks are written using two functions:

  • An inside thunk function, which gets dispatch and getState as arguments
  • The outside creator function, which creates and returns the thunk function

Async logic is typically written in special functions called “thunks”

  • Thunks receive dispatch and getState as arguments
  • Redux Toolkit enables the redux-thunk middleware by default
Thunk function example

Redux-Saga

This is one of videos that help me to understand Saga.

Redux toolkit

In slice file, we create a configure store file

import { configureStore } from "@reduxjs/toolkit";export default configureStore({reducer: {},});

TS version for RKT

Creating Slices of State

Redux Toolkit includes a createSlice function that will auto-generate the action types and action creators for you

  • A “slice” contains the reducer logic and actions related to a specific feature / section of the Redux state
const stockSlice = createSlice({
name : 'stocks'
reducers: {
addStock: (state,action) => {
}
}});export const {addStock} = stockSlice.actions;
export default = stockSlice.reducer

Now, have not dispatch an action. so, useDispatchfunction will help us.

import an action(addStock) and then dispatch an action.

All the new features we’ll add after this will follow the same basic patterns you’ve seen here: adding slices of state, writing reducer functions, dispatching actions, and rendering the UI based on data from the Redux store.

Redux with TypeScript

Redux Saga vs RTK Query

Frequently asked questions

  • The differences between Context API and Redux

1. Why Redux over React Context API?
Although they have similar purpose, React Context has some potential disadvantages like complex setup with bunch of nested JSX Code and performance. One of Redux team members said its still not ready for all Flux-like state propagation(change frequently). React context is not optimized for high-frequency state changes. React-Redux uses the Context api, so you always are using both together. Redux is for state management, Context is for propagating values down the render tree. Not the same thing.

--

--

No responses yet