Learning Redux state management tools

Original link: https://www.iyouhun.com/post-227.html

Redux – Concept

Redux is the most commonly used state management tool (state container) in React

Documentation:

The problem with React:

  • React is just an abstraction layer (UI library) of the DOM, not a complete solution for web applications.
  • Therefore, React is more complicated when it comes to data processing and communication between components.
  • For large and complex applications, these two aspects are the most critical, requiring a dedicated state tool.

Background introduction:

  • In 2014, Facebook proposed the concept of Flux architecture (the concept of front-end state management), which led to many implementations
  • In 2015, Redux appeared, combining Flux with functional programming , and it became the most popular front-end architecture in a short time.
  • Flux is the earliest front-end state management tool. It provides the idea of ​​state management and the corresponding implementation.
  • In addition to Flux, Redux, there are: Mobx and other state management tools

Why do you need Redux?

with-redux.e1b68afc

  • Without Redux (left side of the picture):
    • You can only use React’s own mechanisms such as parent-child component communication, state promotion, etc.
    • Weakness in component communication when dealing with distant relatives (non-father-son) relationships
    • The data flow between components is chaotic, and it is difficult to locate bugs when they occur
  • Using Redux (on the right):
    • Centrally store and manage application state
    • When dealing with component communication problems, ignore the hierarchical relationship between components
    • Simplify communication problems between components in large and complex applications
    • Clear data flow, easy to locate bugs

Redux – core elements

In order to make the responsibilities of each part of the code clear and clear , Redux code is divided into three core concepts: action/reducer/store

  1. What are the responsibilities of the three core concepts
    • action -> reducer -> store
    • action : describe what to do
    • reducer (function): update state
    • store (warehouse): integrate actions and reducers
  2. life by analogy
    1. Action: Equivalent to things to be done in the company, such as software development, testing, cleaning, etc.
    2. reducer: equivalent to the employee of the company, responsible for the work
    3. store: equivalent to the boss of the company
    4. Process: The boss (store) assigns the things to be done in the company (action) to the employee (reducer), and the employee gives the result to the boss after finishing the work.

Redux-core action

An action is an object, the type describes the behavior, and the payload is agreed as a parameter.

explain:

  • action action (noun), action
  • Describe what to do, each feature in the project is an action
  • E.g:
    • Counter case: the counter is incremented by 1, decremented by 1
    • Shopping cart case: get shopping cart data, switch product selection status
    • Items: login, logout, etc.

Features:

  • action only describes what to do
  • action is a JS object that must have a type attribute to distinguish the type of action
  • Depending on the function, additional data (for example, payload ) can be carried, and the corresponding function can be completed with this action

Example:

 // 计数器案例{ type: 'increment' } // +1 { type: 'decrement' } // -1 // 累加10操作{ type: 'increment', payload: 10 } // +10 { type: 'decrement', payload: 10 } // -10 // 购物车案例{ type: 'getGoodsList' } { type: 'changeGoodsState', payload: { id: 1, goodsState: true } }

action creator

Use functions to create action objects to simplify the creation of action objects when using actions multiple times

Example:

 // 1. 不使用Action Creator // 创建多个action 时,需要重复手动创建action 对象,很繁琐{ type: 'decrement', payload: 2 } { type: 'decrement', payload: 8 } // 2. 使用Action Creator const decrement = payload => { return { type: 'decrement', payload } } decrement(2) // => { type: 'decrement', payload: 2 } decrement(8) // => { type: 'decrement', payload: 8 } // 可以动态创建action

Redux-core reducer

  • The name refers to the reduce method in the JS array
  • The reduce method in the array can be used to achieve accumulation (for example, accumulation or accumulation)

effect:

  • Used to handle actions and update state, is where Redux状态更新
  • The function signature is: (prevState, action) => newState
  • Receive the last state and action as parameters, perform different operations according to the type of action, and finally return the new state

in principle:

  • The function must have a return value , even if the state has not changed, it must return to the previous state
  • reducer is a pure function
    • Do not use impure operations like Math.random() / new Date() / Date.now() / ajax requests
  • reducers cannot perform JS side effects
    • Do not modify the current state directly, but create a new state value based on the current state value (replace old with new)
 // 伪代码: // prevState 上一次的状态// action 当前要执行的动作const reducer = (prevState, action) => { return newState }

Example:

 // 示例: // state 上一次的状态// action 当前要执行的动作const reducer = (state, action) => { switch (action.type) { // 计数器增加case 'increment': // 返回新状态// return state + 1 // 根据action 中提供的payload 来决定到底增加多少return state + action.payload // 注意:一定要有default,如果将来reducer 无法处理某个action,就直接将上一次的状态返回即可default: return state } } // 模拟调用reducer(0, { type: 'increment' }) // 本次执行完成后,状态变为:1 reducer(1, { type: 'increment' }) // 本次执行完成后,状态变为:2 reducer(1, { type: 'decrement' }) // 无法处理该action,所以返回上一次状态:1

Summarize:

  • The reducer is where the state is modified. Here, the state is modified according to the type of action.
  • The principle of modification: the new value replaces the old value, cannot send requests and return randomly, and cannot operate global variables

Redux-core store

Associate action and reducer through store

store: Repository, the core of Redux, integrates actions and reducers

  • Features:
    • An application has only one store
    • Maintain the state of the application, get the state: store.getState()
    • When a state update is initiated, an action needs to be dispatched: store.dispatch(action)
    • Receive a reducer as a parameter when creating a store: const store = createStore(reducer)
  • other APIs,
    • Subscribe (listen) state changes: const unSubscribe = store.subscribe(() => {})
    • Unsubscribe from state changes: unSubscribe()

Core code:

 // 提前安装redux import { legacy_createStore as createStore } from 'redux' // 创建store // 参数为:reducer 函数const store = createStore(reducer) // 更新状态// dispatch 派遣,派出。表示:分发一个action,也就是发起状态更新store.dispatch(action) store.dispatch( increment(2) ) // 获取状态const state = store.getState() // --- // 其他API // 监听状态变化const unSubscribe = store.subscribe(() => { // 状态改变时,执行相应操作// 比如,记录redux 状态console.log(store.getState()) }) // 取消监听状态变化unSubscribe()

Redux – the origin of default values

  • As soon as the store is created, Redux will call the reducer once, this time to initialize the default values.
  • First call to reducer reducer(undefined, {type: "@ @redux /INITv.a.4.ttp"})
  • Because the incoming state value is undefined and a random action type, so:
    • The state value is undefined, so the default value we set will take effect state = 10
    • Because it is a random action type, it will definitely go to default and return to the default value of 10
    • Redux gets the state value internally, and uses this state value as the default value of the state in the store
    • Therefore, in the future when we call store.getState() method to get the Redux state value is the default value
 // 导入createStore import { legacy_createStore as createStore } from 'redux' // 创建store const store = createStore(reducer) // action => { type: 'increment' } function reducer(state = 10, action) { console.log('reducer:', state, action) switch (action.type) { case 'increment': return state + 1 default: return state } } store.dispatch(increment()) // 相当于:store.dispatch({ type: 'increment' }) console.log('store 状态值为:', store.getState())

Redux – execution process analysis

  1. When creating a store, Redux will first call the reducer to get the default state
  2. Dispatch action store.dispatch(action) to update state
  3. Redux store calls the reducer to pass in: the last state (in the current example: 10 ) and action ( { type: 'increment' } ), calculate the new state and return
  4. After the reducer is executed, the latest state is handed over to the store, the store replaces the old state with the latest state, and the state is updated.
 import { legacy_createStore as createStore } from 'redux' const store = createStore(reducer) // reducer(10, { type: 'increment' }) function reducer(state = 10, action) { console.log('reducer:', state, action) switch (action.type) { case 'increment': return state + 1 default: return state } } console.log('状态值为:', store.getState()) // 10 // 发起更新状态: // 参数: action 对象store.dispatch({ type: 'increment' }) // 相当于: reducer(10, { type: 'increment' }) console.log('更新后:', store.getState()) // 11

Pure Functions & JS Side Effects

Pure function:

 // 纯函数: const add = () => { return 123 } add() // 123 add() // 123 const add = (num1, num2) => { return num1 + num2 } add(1, 2) // 3 add(1, 2) // 3 const add = (obj) => { return obj } add({ name: 'jack' }) // { name: 'jack' } add({ name: 'jack' }) // { name: 'jack' } // 不是纯函数: const add = () => { return Math.random() } add() // 0.12311293827497123 add() // 0.82239841238741814

JS side effects:

  • A function or other operation is said to have side effects if it modifies the value of a state variable outside of its local environment
 // 无副作用const add = (num1, num2) => { return num1 + num2 } add(1, 3) // 有副作用: let c = 0 const add = (num1, num2) => { // 函数外部的环境产生了影响,所以是有副作用的c = 1 return num1 + num2 } add(1, 3) // 有副作用const add = (obj) => { // 因为直接修改了参数的值,对外部的数据产生了影响obj.num = 123 return obj } const o = {} add(o) console.log(o) // { num: 123 }

This article is reprinted from: https://www.iyouhun.com/post-227.html
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment