Learn how to use Redux

Redux is a state manager, usually used with React, but it is not tied to the library. Learn Redux by reading this easy to understand guide

Why you need Redux

Redux is a state manager that is usually used with React, but it is not tied to the library-it can also be used with other technologies, but for the sake of illustration, we will stick to React.

As you read, React has its own way of state management.Beginner's Guide to ReactHere, I introduced how to manage state in React.

In simple cases, it is possible to move the state up in the tree, but in complex applications, you may find that almost all states are moved up using props, and then the props are moved down and down.

React was introduced in version 16.3.0Context API, Which makes Redux redundant in the use case of accessing state from different parts of the application, so unless you need specific features provided by Redux, consider using the Context API instead of Redux.

Redux is a way to manage application state and move it toExternal global store.

You need to master some concepts, but once completed, Redux is a very simple way to solve the problem.

Redux is very popular in React applications, but it is by no means unique to React: almost all popular frameworks have bindings. That said, I will use React as its main use case to illustrate.

When should I use Redux?

Redux is ideal for medium to large applications. You should only use Redux if you are using the default state management React or other libraries used to manage state.

Simple applications do not need it at all (simple applications are not wrong).

Immutable state tree

In Redux, the entire state of the application is represented asOne JavaScriptObject, calledstatusorState tree.

We call itImmutable state treeBecause it is read-only: it cannot be changed directly.

Only one can be assignedaction.

action

OneactionYesA JavaScript object that describes the change in a minimal way(Provide only required information):

{
  type: 'CLICKED_SIDEBAR'
}

// e.g. with more data { type: ‘SELECTED_USER’, userId: 232 }

The only requirement for an action object is to have atypeThe attribute, whose value is usually a string.

Action type should be constant

In simple applications, the operation type can be defined as a string.

When the application grows, it is best to use constants:

const ADD_ITEM = 'ADD_ITEM'
const action = { type: ADD_ITEM, title: 'Third item' }

And separate the operation in its own file, and then import it

import { ADD_ITEM, REMOVE_ITEM } from './actions'

Action creator

Action creatorIt is a function to create an action.

function addItem(t) {
  return {
    type: ADD_ITEM,
    title: t
  }
}

Generally, you can run the action creator in conjunction with the trigger scheduler:

dispatch(addItem('Milk'))

Or by defining the action dispatcher function:

const dispatchAddItem = i => dispatch(addItem(i))
dispatchAddItem('Milk')

reducer

When an action is triggered, something must happen and the state of the application must change.

This is workreducer.

What is a reducer

A kindreducerIs anPure functionIt calculates the next state tree based on the previous state tree and the dispatched operation.

;(currentState, action) => newState

Pure functions accept input and return output without changing the input or anything else. Therefore, the reducer returns a new state to replace the previous state.

What the reducer should not do

The reducer should be a pure function, so it should:

  • Never change its argument
  • Never change the state, but create a new stateObject.assign({}, ...)
  • Never produce side effects (no API call will change anything)
  • Never call impure functions, these functions will change their output based on factors other than the input (for example,Date.now()orMath.random())

No reinforcement, but you should follow the rules.

Multiple reducers

Since the state of a complex application can be really wide, there is no single reducer, but many reducers are used for any type of action.

Simulation of reducer

Essentially, Redux can be simplified by the following simple model:

status

{
  list: [
    { title: "First item" },
    { title: "Second item" },
  ],
  title: 'Groceries list'
}

Action checklist

{ type: 'ADD_ITEM', title: 'Third item' }
{ type: 'REMOVE_ITEM', index: 1 }
{ type: 'CHANGE_LIST_TITLE', title: 'Road trip list' }

Reducer in each state

const title = (state = '', action) => {
    if (action.type === 'CHANGE_LIST_TITLE') {
      return action.title
    } else {
      return state
    }
}

const list = (state = [], action) => { switch (action.type) { case ‘ADD_ITEM’: return state.concat([{ title: action.title }]) case ‘REMOVE_ITEM’: return state.filter(item => action.index !== item.index) default: return state } }

Reducer in the whole state

const listManager = (state = {}, action) => {
  return {
    title: title(state.title, action),
    list: list(state.list, action)
  }
}

store

ThisShopIs an object:

  • On holdOf the application
  • Exposed statebygetState()
  • Allow usupdate statusbydispatch()
  • Allow us to (un)registerState change listenerusesubscribe()

A store isUniqueIn the application.

This is how to create a store for the listManager application:

import { createStore } from 'redux'
import listManager from './reducers'
let store = createStore(listManager)

Can I use server-side data to initialize storage?

of course,Just past a start state:

let store = createStore(listManager, preexistingState)

Get status

store.getState()

update status

store.dispatch(addItem('Something'))

Listening status changes

const unsubscribe = store.subscribe(() =>
  const newState = store.getState()
)

unsubscribe()

data flow

The data flow in Redux is alwaysunidirectional.

You calldispatch()In the store, through an action.

The store is responsible for passing the operation to the Reducer and generating the next state.

The store will update the status and warn all listeners.

Download mine for freeResponse Handbook


More response tutorials: