小编典典

React Hooks-引擎盖下发生了什么?

reactjs

我一直在尝试React Hooks,它们似乎确实简化了诸如存储状态之类的事情。但是,他们似乎通过魔术来做很多事情,而我找不到关于它们实际工作方式的好文章。

看起来很神奇的第一件事是,每次调用setXXX方法时,调用诸如useState()之类的函数如何导致功能组件的重新渲染?

当功能组件甚至没有能力在Mount / Unmount上运行代码时,诸如useEffect()之类的东西如何伪造componentDidMount?

useContext()如何真正获得对上下文的访问,甚至如何知道正在调用哪个组件?

而且,这甚至还没有覆盖已经出现的所有第三方钩子,例如useDataLoader,它允许您使用以下内容…

const { data, error, loading, retry } = useDataLoader(getData, id)

数据,错误,加载和重试如何在组件更改时重新呈现?

抱歉,有很多问题,但是我想大多数问题可以归结为一个问题:

钩子后面的函数实际上如何访问正在调用它的功能/无状态组件,以便它可以记住重新渲染之间的内容并使用新数据启动重新渲染?


阅读 313

收藏
2020-07-22

共1个答案

小编典典

React钩子利用组件的隐藏状态,它存储在光纤内部,光纤是与组件实例相对应的实体(从广义上讲,因为功能组件不会将实例创建为类组件)。

它是React渲染器,它使钩子可以访问各自的上下文,状态等。顺便说一下,它是React渲染器,它调用组件函数。因此,它可以将组件实例与在组件函数内部调用的挂钩函数相关联。

此代码段说明了其工作原理:

let currentlyRenderedCompInstance;
const compStates = new Map(); // maps component instances to their states
const compInstances = new Map(); // maps component functions to instances

function useState(initialState) {
  if (!compStates.has(currentlyRenderedCompInstance))
    compStates.set(currentlyRenderedCompInstance, initialState);

  return [
    compStates.get(currentlyRenderedCompInstance) // state
    val => compStates.set(currentlyRenderedCompInstance, val) // state setter
  ];
}

function render(comp, props) {
  const compInstanceToken = Symbol('Renderer token for ' + comp.name);

  if (!compInstances.has(comp))
    compInstances.set(comp, new Set());

  compInstances.get(comp).add(compInstanceToken);

  currentlyRenderedCompInstance = compInstanceToken;

  return { 
    instance: compInstanceToken,
    children: comp(props)
  };
}

与如何useState通过访问当前呈现的组件实例令牌类似currentlyRenderedCompInstance,其他内置的钩子也可以执行此操作并维护该组件实例的状态。

2020-07-22