react3-Redux

Redux

  1. state manager
  2. Centrally manage the state data in the application and update the state data in a predictable way
  3. react-redux The official website of the binding library
    redux has no direct relationship with react, so to use redux for state management in react, an additional binding library is usually required: react-redux

concept

  1. store : warehouse, which is a container, mainly used to centrally manage the state in the application

  2. state : state, which is the state data that each component needs to share

  3. action : is an ordinary object, usually used to describe what happened. There are generally two attributes in this object: type and payload

  4. action creator : action creation function, which is a function structure, mainly used to create action objects to realize action reuse

  5. reducer : is a pure function for synchronously updating state data. This function takes state and action as parameters and returns the new state state data. The function signature is: (state, action) => newState

    注:纯函数
    返回值依赖于参数
    函数主体内部不产生任何副作用
    
  6. Reducers must conform to the following rules:

  • Calculate a new state value using only the state and action parameters
  • Direct modification of state is prohibited. Immutable updates must be made by copying the existing state and making changes to the copied value
  • You can use lodash to implement deep copy
  • Disallow any asynchronous logic, code that relies on random values, or causes other "side effects"
  1. The logic inside a reducer function typically follows these steps:
  • Check if reducer cares about this action
  • If yes, copy the state, update the state copy with the new value, and return the new state, otherwise, return the original state unchanged
  • dispatch: It is a function that passes action as a parameter to call the reducer for state update (you cannot directly call reducer() for state update in the component, note that the call of the reducer() function is encapsulated in the dispatch() function body) .)
  • selector: is a function used to extract fragments from the store's state state tree.

three principles

single source of truth

The state of the entire application is stored in an object tree, and this object tree only exists in the only store

State is read-only

The only way to change the state is to trigger the action (that is, call the dispatch(action) method), and the action is a common object used to describe the event that has occurred

Use pure functions to perform modifications

To describe how actions change the state tree, you need to write reducers

use

  1. Install
  1. Create reducers
  • Create the .src/actions/constants.js directory
/** action type 的取值 */
export const ADD_TO_CART = Symbol('add_to_cart')
  • Create action creator
    Create ./src/actions/cart.js directory, define action creator (action creation function), such as:
/**
 * 定义 action creator (action创建函数),用于创建 action 对象,以便于复用 action 对象
 */

import {
    
     ADD_TO_CART } from "./constants"

/**
 * 用于创建添加到购物车时使用的 action 对象
 */
export const addToCartAction = (product) => {
    
    
  return {
    
    
    type: ADD_TO_CART,
    payload: product,
  }
}
  • Create the ./src/reducers/cart.js directory and define the reducer function, such as:
/**
 * 实现购物车状态数据管理
 */

import _ from 'lodash'
import {
    
     ADD_TO_CART, REMOVE_FROM_CART } from "../actions/constants"

/**
 * 初始状态数据
 */
const initialState = {
    
    
  cart: [],
}

/**
 * reducer 函数,是一个纯函数,用于同步更新状态数据
 * @param {*} state 旧状态数据
 * @param {*} action action对象,有 type 和 payload 属性 
 * @returns 返回新的状态数据
 */
const cartReducer = (state = initialState, {
     
      type, payload }) => {
    
    

  /** 对 state 进行深克隆 */
  const copyState = _.cloneDeep(state)

  /**
   * 使用 switch 多分支选择,来判断当前 action 的动作类型
   */
  switch (type) {
    
    
    case ADD_TO_CART: // 添加购物车
      copyState.cart.push(payload)
      return copyState
    case REMOVE_FROM_CART: // 从购物车中删除商品
      copyState.cart = copyState.cart.filter(prod => prod.id !== payload.id)
      return copyState
    default:
      return state
  }
}

export default cartReducer
  • ./src/reducers/index.js merges independent reducers into a root reducer, such as:
/**
 * 将多个独立的 reducer 合并为一个根 reducer
 */

import {
    
     combineReducers } from 'redux'
import cartReducer from './cart'

const rootReducer = combineReducers({
    
    
  shoppingCart: cartReducer,
})

export default rootReducer
  • Create a Store
    Create a ./src/store directory and define a Store:
/**
 * 创建 Store 仓库
 */

import {
    
     createStore } from 'redux'
import rootReducer from '../reducers'

/**
 * 基于根 reducer 来创建 store
 */
const store = createStore(rootReducer)

export default store
  • The Store connected to Redux in the entry file .src/index.js component
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import {
    
    Provider} from "react-redux";
import store from "./store";

ReactDOM.render(
 <Provider store={
    
    store}>
         <App/>
 </Provider>,
  document.getElementById('root')
)
  • used in the file
import React from 'react'
import {
    
    useDispatch, useSelector} from "react-redux"; // 引入并结构出useDispatch(使用方法,改变数据)useSelector(拿到数据)
impot {
    
    addToCartActio} fron "../actions/cart.js"

function React() {
    
    
  const dispatch=useDispatch()
  const cart=useSelector(state=>state.shoppingCart.cart) // 格式一个回调函数,state.空间名字.仓库数据名字
  const clickHandler=()=>{
    
    
  		dispatch(addToCartAction({
    
    id:0,title:'商品信息'})) // 触发的actions事件
  }
  return (
    <div onClick={
    
    clickHandler}>react</div>
  )
}
export default React

asynchronous task

  1. Handling asynchronous tasks requires a three-party package
  • yarn add redux-thunk
  1. Introduced in the store
import {
    
    createStore,applyMiddleware} from "redux";
import logger from 'redux-logger' // 记录仓库状态数据
import thunk from 'redux-thunk' // 异步仓库任务处理
import rootReducer from "../reducers/index"

const store = createStore(rootReducer,applyMiddleware(logger,thunk))
export default store
  1. Written in tasks that require asynchronous processing, such as logging network requests in actions
import {
    
    LOGIN_SUCCESS,LOGIN_FAILED,LOGIN_RESET} from '../constants/action-types'
import {
    
    postLogin} from '../api/user'

export const loginSuccessAction=info=>{
    
    
    return {
    
    
        type:LOGIN_SUCCESS,
        payload:info,
    }
}
// 重置
export const loginResetAction=()=>{
    
    
    return{
    
    
        type: LOGIN_RESET,
    }
}
// 异步请求登录网络
export const loginAsyncAction=(info)=>{
    
    
    /**
     * 返回的这个函数,会自动被 redux-thunk 中间件调用执行。
     * 在调用执行这个函数时,会自动传递 dispatch 作为参数。
     * 不要求返回的这个函数保持纯净(即可以包含异步逻辑)
     */
    return async dispatch=>{
    
    
        const {
    
    status,data}=await postLogin(info)
        if(status===200){
    
     // 登录成功
            dispatch(loginSuccessAction(data))
            return true
        }else {
    
     // 登录失败
            dispatch({
    
    
                type:LOGIN_FAILED
            })
            return false
        }
    }

}

Guess you like

Origin blog.csdn.net/weixin_64925940/article/details/125149611