7

文档说所有 React 组件在其 props 方面都必须像纯函数一样工作。 https://facebook.github.io/react/docs/components-and-props.html,但没有解释背后的真正原因,这是为什么呢?

4

4 回答 4

2

一个 React 组件应该是纯的,这意味着它的render方法的结果应该完全取决于propsstate,并且对于相同的属性和状态render应该给出相同的结果。

如果 render 不是纯的,则意味着它可以针对相同的输入返回不同的结果,因此 React 无法根据组件的更改来判断 DOM 的哪些部分需要更新。这很关键,因为 React 的性能取决于此。为什么?这有点复杂。

基于状态定义 UI 并在每次状态的任何部分发生变化时让 UI 重新呈现自身是令人惊奇的。但是您可以想象,每次更改某些内容时对整个 DOM 进行完全重新渲染会非常缓慢。React 通过检查 DOM 反映新状态所需的最小更改量来解决这个问题。它基于每个组件接收到的属性和状态知道这些更改是什么,并且可以判断如果组件的任何属性或状态发生更改,它是否需要更新组件。

以这棵树作为组件层次结构的例子

状态树

这里我们更改h为 8,所以我们也更改了f因为his a child of f,我们也更改了cbecause fis child ofc等等。

这里的关键是考虑 React 如何检查组件树。它会从根开始,然后看到它发生了变化。然后它会检查所有的孩子,并实现只c改变,所以不需要检查所有的ab分支。然后它会检查c分支并实现只f更改所以不需要检查eand g。该操作在每个组件上完成,以计算最小更改量以及需要更新的内容。

如果在任何时候你可以改变组件的渲染方式,这意味着 React 将需要检查所有分支及其所有子项以了解发生了什么变化,因为它不能依赖状态和道具来了解分支何时发生变化如何。这将非常缓慢,并使整个 React 框架不可行。

于 2017-02-01T18:52:46.710 回答
1

我会说是因为跟踪组件状态的变化。如果不是纯的,每次执行都会产生副作用。这样一来,就很难知道发生了什么变化,以及如何对这些变化做出反应。

换句话说,纯函数具有相同的输出和相同的输入。使管理属性和跟踪更改时变得更加容易,从而以更轻松且可预测的方式对更改做出反应。

于 2017-02-01T17:17:43.600 回答
1

如果它们不是与其 props 相关的纯函数,那么它将违反 react 提供和依赖的整个层次结构/委托结构。

假设您有两个组件,组件 A 和组件 B,组件 A 是组件 B 的父组件。组件 A 基于某种数据有自己的状态。当您将其状态的一部分作为 prop 传递给组件 B 时,您正在建立两个组件之间的合约,组件 B 将委托给组件 A 以获得所述 prop 的值。

从某种意义上说,这是两个组件之间的合同,并且不违反合同的唯一方法是组件 B 不会直接更改或更改传递下来的 prop。这就是纯函数的含义,它不会直接改变道具。当然,您可以克隆道具然后更改它,但是您希望这不会违反合同,因为那时它们没有引用相同的值。但是如果你直接改变 props,你也会改变父组件的值。这可能会导致意外的副作用,并导致 react shadow dom 差异算法出现问题。

这是官方反应文档中的解释

https://facebook.github.io/react/blog/2015/02/24/streamlining-react-elements.html#problem-mutating-props-you-dont-own

于 2017-02-01T18:26:46.257 回答
0

你会发现“为什么”理解React 用于渲染的Reconciliation 算法。

在这里,您拥有了解所需内容所需的所有信息。

Marco Scabbiolo 的回答中很好地解释了其中的一部分,但是如果您想了解 React 的工作方式,我强烈建议您阅读我建议的帖子。

在这里发布答案对于一个帖子来说太过分了,而且没有必要,因为 React Team 已经解释过了。这就是为什么我更喜欢直接给你源。

于 2017-02-01T19:15:02.283 回答