• React@16.x(25)useReducer


    1,介绍

    这也是官方的一个HOOK,目的是更方便的使用 Redux

    Redux 后续会详细介绍。它的主体思想沿用了 Flux 数据流框架(也是 FaceBook 出品的)的思想,Vuex 也是同样的实现。

    1.1,Flux 的设计思想

    1. 数据是单项流动的。
    2. 数据存储在数据仓库 state 中(可以将 useStatestate 简单理解为数据仓库)。
    3. action 是改变数据的唯一原因,它本质上是一个对象,有2个属性
      1. type,字符串,表示改变数据的动作类型;
      2. payload,any类型,表示动作的附加信息,也就是额外的参数。

      例如,添加一个学生:{ type: 'addStu', payload: { 学生对象的各种信息 } }
      例如,删除一个学生:{ type: 'deleteStu', payload: 学生id }

    4. reducer 改变数据的具体实现,是一个函数:
      1. 有2个参数
        1. state,表示当前数据仓库中的数据;
        2. action
      2. 必须有返回值,表示数据仓库变化后的数据。另外,Flux 要求对象是不可变的,所以要修改 state 必须创建新的对象。
      3. 必须是纯函数,不能有任何副作用。
      4. 不能直接调用,必须通过辅助函数 dispatch
    5. dispatch 是一个辅助函数,用于触发 reducer。该函数仅接收一个参数 action,并调用 reducer 来改变 state

    2,实现

    2.1,引入

    先看个简单例子:

    export default function App() {
        const [n, setN] = useState(0);
        return (
            <div>
                <button
                    onClick={() => {
                        setN(n - 1);
                    }}
                >
                    -
                </button>
                <span>{n}</span>
                <button
                    onClick={() => {
                        setN(n + 1);
                    }}
                >
                    +
                </button>
            </div>
        );
    }
    

    用 Flux 的思想改造:

    function reducer(state, action) {
        let newState = state;
        if (action.type === "minus") {
            newState = state <= 0 ? 0 : state - 1;
        } else if (action.type === "add") {
            newState = state + 1;
        }
        return newState;
    }
    
    export default function App() {
        const [n, setN] = useState(0);
        function dispatch(action) {
            const newN = reducer(n, action);
            setN(newN);
        }
        return (
            <div>
                <button
                    onClick={() => {
                        dispatch({ type: "minus" });
                    }}
                >
                    -
                </button>
                <span>{n}</span>
                <button
                    onClick={() => {
                        dispatch({ type: "add" });
                    }}
                >
                    +
                </button>
            </div>
        );
    }
    

    注意,通过 Flux 的思想,只是为了把逻辑拆分的更细,便于管理状态 state

    我要改变数据(dispatch),至于如何实现(reducer)并不关心。

    而对使用状态的组件来说,影响并不大。因为完全可以直接使用 reducer 这个自定义函数。

    2.2,实现 useReducer

    dispatch 的实现很简单,所以可以考虑做成一个通用的 HOOK:useReducer

    import { useState } from "react";
    
    export const useReducer = (reducerFunc, initState) => {
        const [state, setState] = useState(initState);
        function dispatch(action) {
            const newState = reducerFunc(state, action);
            setState(newState);
        }
        return [state, dispatch];
    };
    

    使用:

    export default function App() {
        const [n, dispatch] = useReducer(reducer, 0);
        // 其他内容...
    }
    

    3,官方实现

    React 考虑到这一点,所以官方实现了 useReducer 这个HOOK函数,并且还有第3个可选参数:
    该函数将 useReducer 的第2个参数作为它的参数,返回值作为 useReducer 中的 state 初始值。

    import { useReducer } from "react";
    

    改造下自己实现的:

    import { useState } from "react";
    
    /**
     * 通用的useReducer函数
     * @param { function } reducer reducer函数
     * @param { any } initialState 初始状态
     * @param { function } initFunc 计算初始值的函数
     */
    export const useReducer = (reducerFunc, initState, initFunc) => {
        const [state, setState] = useState(initFunc ? initFunc(initState) : initState);
        function dispatch(action) {
            const newState = reducerFunc(state, action);
            setState(newState);
        }
        return [state, dispatch];
    };
    

    以上。

  • 相关阅读:
    iwebsec靶场 SQL注入漏洞通关笔记5- updatexml注入(报错型盲注)
    基于Spring Boot的大学校园防疫与服务系统毕业设计源码111556
    Prometheus+Grafana可视化监控【MySQL状态】
    模板进阶&&模板分离编译的问题与解决
    头歌实践--实验八 回溯法
    Java(99):Java针对Mongo数据库的工具类MongoDBUtil
    Vue官方文档(38):全局自定义指令
    Vagrant+VirtualBox+Docker+MySQL+Redis+Nacos
    React Router 6 快速上手
    iOS AppStore上架流程图文详解
  • 原文地址:https://blog.csdn.net/qq_40147756/article/details/139577815