【问题标题】:How does React implement hooks so that they rely on call orderReact 如何实现 hooks 使它们依赖于调用顺序
【发布时间】:2019-07-07 11:07:47
【问题描述】:

React Hooks useState 可以将本地状态附加到无状态功能组件,例如

const [name, setName] = useState('tom')
const [age, setAge] = useState(25)

我想知道执行上面两行之后本地状态对象树是什么样子的? Rules of Hooks 讲述了如何处理状态

React 依赖于 Hook 的调用顺序

或者本地状态根本不是对象树,只是一个数组?

提前致谢!

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    钩子在内部被实现为一个队列,每个钩子由一个节点表示,该节点具有对下一个的引用。

    来自文档:

    每个内存单元都有一个内部列表 零件。它们只是 JavaScript 对象,我们可以在其中放置一些数据。 当你调用 useState() 之类的 Hook 时,它会读取当前单元格(或 在第一次渲染期间初始化它),然后将指针移动到 下一个。这就是多个 useState() 调用每个 get 的方式 独立的地方州。

    架构类似于

    {
      memoizedState: 'A',
      next: {
        memoizedState: 'B',
        next: {
          memoizedState: 'C',
          next: null
        }
      }
    }
    

    单个钩子的架构如下。可以在implementation中找到

    function createHook(): Hook {
      return {
        memoizedState: null,
    
        baseState: null,
        queue: null,
        baseUpdate: null,
    
        next: null,
      };
    }
    

    让钩子以它们的方式运行的关键属性是memoizedStatenext

    在每个函数组件调用之前,prepareHooks() 将被调用,其中当前纤程及其在钩子队列中的第一个钩子节点将被存储在全局变量中。这样,任何时候我们调用一个钩子函数(useXXX())它都会知道在哪个上下文中运行。

    更新后finishHooks() 将被调用,其中钩子队列中第一个节点的引用将存储在memoizedState 属性中的渲染纤维上

    【讨论】:

    • 钩子不允许传递名称参数来解决这个问题是有原因的吗?例如useState("tom", "state_1") 并在第二个参数丢失时退回到顺序?甚至可能存在应在第一次渲染时调用所有钩子或延迟调用的合理行为的约束?或者它是否意味着强制在每次渲染时调用所有钩子? (从某种意义上说,钩子名称可以解决排序问题,但有必要在每次渲染时调用所有钩子)
    猜你喜欢
    • 2019-09-11
    • 2020-04-26
    • 2020-12-14
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    • 2021-10-21
    相关资源
    最近更新 更多