• React Hooks useReducer 使用详解+实现原理+源码分析


    简介

    useReducer => useState 的高级方案

    官网说 useReduceruseState 的替代方案,我觉得说是 useState 的高级方案更合适
    因为 useReducer 本质的作用也是更新 state,另外它还支持自定义集成多种更新同一个 state 的规则

    使用方法

    useReducer定义.png

    函数签名如下:

    const [state, dispatch] = useReducer(reducer, initialArg, init);
    
    • 1

    @param 第一个参数为处理 state 改变规则的函数 reducer

    reducer 的参数含义:

    - @param 第一个参数为要处理的 state  
    - @param 第二个参数为 dispatch 绑定的 action(即 dispatch 函数的入参)  
    - @return 返回更新 state  
    
    • 1
    • 2
    • 3

    @param 第二个是初始 state

    @param 第三个是可选的处理初始 state 的函数 init

    @return 返回当前 state

    @return 返回 state 对应的 dispatch 方法(触发 state 更新的方法 => 类比 setState

    // 处理 初始state
    function init(initialCount) {
      return {count: initialCount};
    }
    
    // 处理 state 更新规则的函数,并返回新的 state
    function reducer(state, action) {
      switch (action.type) {
        case 'increment':
          return {count: state.count + 1};
        case 'decrement':
          return {count: state.count - 1};
        case 'reset':
          return init(action.payload);
        default:
          throw new Error();
      }
    }
    
    // 计数组件
    function Counter({initialCount}) {
      const [state, dispatch] = useReducer(reducer, initialCount, init);
      return (
        <>
          Count: {state.count}
          <button
            onClick={() => dispatch({type: 'reset', payload: initialCount})}>
            Reset
          </button>
          <button onClick={() => dispatch({type: 'decrement'})}>-</button>
          <button onClick={() => dispatch({type: 'increment'})}>+</button>
        </>
      );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    源码分析👇👇👇

    Hook 公共的执行环境判断在useState文章里介绍过点此跳转查看
    我们主要来看下 moun 阶段里 mountReducer 的实现 ,和 update 阶段里 updateReducer 的实现。

    mount 阶段

    mount 阶段 useReducer 调用 mountStateuseReducer 调用 mountReducer
    唯一区别就是它们创建的 queuelastRenderedReducer 不一样,useState 默认传入 basicStateReducer => useState 就是有默认 reducer 参数的 useReducer
    mountReducer源码.png

    update 阶段

    updateReducer源码.png

    其中循环处理 state 更新队列的原理如下图所示:
    场景:现有两次更新 update1、update2,新的更新 update3、update4

    循环处理state更新队列的原理流程图.jpg

    总结:

    其实看到最后啊,我们发现 useStateuseReducer 都只是进行数据更新的处理操作,而把新数据更新渲染到页面上,是 fiber 做的事。

    useReducer 里会通过 markWorkInProgressReceivedUpdate 方法标记(也就是通知给 fiber)完成 update 的整合工作,接下来在经过 fiber 的调度,通知浏览器,进而表现在页面上。

    这也就导致了函数组件内部获取状态不能实时获取到最新状态的原因,但是 dispatch 提供了函数式入参,这样 react 在执行 queue 的时候,会传递上一步的 state 值到当前函数中。

    setCount(prevCount => prevCount + 1)}
    
    • 1
  • 相关阅读:
    Linux 二进制分析-Linux环境和工具(chapter 1)
    Mysql允许远程访问
    SpringCloud 简介
    MySQL基础(一)---基础认知及操作
    TP5 中 FIND_IN_SET的使用方法 精准匹配,字段值以“,”隔开查询
    Flutter 知识点
    实验三、拓扑布局和建立小型网络《计算机网络》
    Ai-WB2模组HTTP 客户端 POST请求方法
    数据结构——树(树的基本概念)
    【模型剪枝】| yolov5 模型分析及剪枝
  • 原文地址:https://blog.csdn.net/weixin_44137575/article/details/127748164