React Hooks - 引擎盖下发生了什么? [英] React Hooks - What's happening under the hood?

查看:84
本文介绍了React Hooks - 引擎盖下发生了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使用React Hooks,它们似乎简化了存储状态等操作。然而,他们似乎通过魔术做了很多事情,我找不到一篇关于他们实际工作方式的好文章。

I've been trying out React Hooks and they do seem to simplify things like storing state. However, they seem to do a lot of things by magic and I can't find a good article about how they actually work.

第一件似乎是神奇的事情是什么调用像useState()这样的函数会在每次调用它返回的setXXX方法时重新渲染你的函数组件?

The first thing that seems to be magic is how calling a function like useState() causes a re-render of your functional component each time you call the setXXX method it returns?

useEffect()之类的东西怎么样?假设一个componentDidMount,当功能组件甚至无法在Mount / Unmount上运行代码时?

How does something like useEffect() fake a componentDidMount when functional components don't even have the ability to run code on Mount/Unmount?

useContext()实际上是如何访问上下文的?它甚至知道哪个组件正在调用它?

How does useContext() actually get access to the context and how does it even know which component is calling it?

这甚至没有开始覆盖所有已经出现的第三方钩子,如useDataLoader,它允许你使用以下...

And that doesn't even begin to cover all of the 3rd party hooks that are already springing up like useDataLoader which allows you to use the following...

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

如果组件发生变化,数据,错误,加载和重试如何重新渲染?

How do data, error, loading and retry re-render your component when they change?

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

Sorry, lots of questions but I guess most of them can be summed up in one question, which is:

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

推荐答案

React hook利用组件的隐藏状态,它存储在光纤,光纤是一个对应于组件实例的实体(从更广泛的意义上说,因为功能组件不会创建实例作为类组件) 。

React hook makes use of hidden state of a component, it's stored inside a fiber, a fiber is an entity that corresponds to component instance (in a broader sense, because functional components don't create instances as class components).

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

It's React renderer that gives a hook the access to respective context, state, etc. and incidentally, it's React renderer that calls component function. So it can associate component instance with hook functions that are called inside of component function.

此片段解释了它的工作原理:

This snippet explains how it works:

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 访问当前呈现的组件实例令牌,其他内置挂钩也可以执行此操作并维护此组件实例的状态。

Similarly to how useState can access currently rendered component instance token through currentlyRenderedCompInstance, other built-in hooks can do this as well and maintain state for this component instance.

这篇关于React Hooks - 引擎盖下发生了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆