当前位置: 首页 > 知识库问答 >
问题:

反应钩——引擎盖下面发生了什么?

宋新知
2023-03-14

我一直在尝试React钩子,它们似乎可以简化存储状态之类的事情。然而,他们似乎用魔法做了很多事情,我找不到一篇关于他们如何实际工作的好文章。

第一件看起来很神奇的事情是,调用像useState()这样的函数是如何在每次调用setXXX方法时导致函数组件的重新渲染的?

当功能组件甚至不具备在挂载/卸载上运行代码的能力时,像use效应()这样的东西是如何伪造组件的?

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

这甚至还没有开始覆盖所有第三方钩子,这些钩子已经像useDataLoader一样涌现出来,它允许您使用以下内容。。。

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

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

对不起,有很多问题,但我想大部分问题都可以归结为一个问题,那就是:

钩子后面的函数实际上是如何访问调用它的函数/无状态组件的,以便它能够在重新呈现和使用新数据启动重新呈现之间记住事情的?

共有3个答案

齐涛
2023-03-14

我建议你读书https://eliav2.github.io/how-react-hooks-work/

它包括关于使用react钩子时发生了什么的详细解释,并用许多交互式示例进行演示。

注意-本文没有用技术术语解释React如何安排后续阶段的调用,而是演示React用于安排后续阶段调用的规则。

杨良平
2023-03-14

丹·阿布拉莫夫几天前刚刚写了一篇博文,内容包括:

https://overreacted.io/how-does-setstate-know-what-to-do/

第二部分详细介绍了useState之类的钩子。

对于那些有兴趣深入了解一些实现细节的人,我这里有一个相关的答案:react钩子如何确定它们所针对的组件?

酆君墨
2023-03-14

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

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可以访问当前呈现的组件实例令牌通过当前的RenderedCompInstance,其他内置钩子也可以做到这一点,并维护该组件实例的状态。

 类似资料:
  • 问题内容: 我一直在尝试React Hooks,它们似乎确实简化了诸如存储状态之类的事情。但是,他们似乎通过魔术来做很多事情,而我找不到关于它们实际工作方式的好文章。 看起来很神奇的第一件事是,每次调用setXXX方法时,调用诸如useState()之类的函数如何导致功能组件的重新渲染? 当功能组件甚至没有能力在Mount / Unmount上运行代码时,诸如useEffect()之类的东西如何伪

  • 我目前正在用C#编写一个纯粹出于学术目的的JVM(也许将来会构建一个混合的.NET和Java/Scala应用程序)。 我编写了一个简单的JAVA类: 并将其编译为。当我使用我的反编译程序(我已经将其作为JVM的一部分编写)反编译它时,我看到这个方法的如下说明: 在常量池中查找索引处的常量时,我看到一个InvokeDynamic-Constant条目,其中包含以下数据: 我想这是有道理的(我更多的是

  • 我必须评估Codename One,但我找不到关于部署在底层是如何工作的以及最终结果是什么的信息。他们是否将我的Java代码交叉编译为类似于RoboVM的真实本机代码,他们是否使用类似于Gluon的JVM,或者他们有自己的JVM?

  • 您都知道将依赖项放入pom.xml文件并运行“MVN clean Install”的过程。当这个命令运行时,依赖项的jar文件被下载到。m2存储库中。 当我们使用IntelliJ和run/debug配置窗口运行应用程序时,IntelliJ如何知道在哪里查找依赖项的jar文件?IntelliJ中的每个GUI操作实际上都取代了命令行操作。当我们单击“运行”按钮时,在“幕后”提交的命令行操作是什么。我相

  • 问题内容: 在阅读了戴夫·切尼(Dave Cheney)关于Go的地图的博客文章之后,对我来说,还有几件事尚不清楚。 TLDR: 为什么它们无序? 实际值存储在哪里? 深入研究运行时程序包后,我发现基本的映射结构如下: -是存储区数组,其中索引是键的哈希值的低位,其中存储区为: ..好吧,这只是每个项目是键的哈希值的第一个字节的数组。键值对存储为(每个存储桶八对)。但是到底在哪里?考虑到映射可能包

  • 我想在我的项目中使用Spring Data Elasticsearch,我看到了这一点: 我的方法是只使用Spring数据Elasticsearch来执行CRUD操作(类似ORM),使用高级REST客户端进行搜索和所有其他操作。因此,我想知道ElasticsearchRepository使用哪个客户端来执行其操作,以及代码是否在Elasticsearch的8.0版中不再有效 使用3.1.5版仍然是