我使用Reaction的渲染器进行了一些测试,以分析其渲染行为

2020-10-30 12:58:30

在这篇文章中,我们将运行一些实验,看看Reaction的渲染器是如何工作的,并了解它的一些有保证的(剧透:我会经常使用这个词😅)行为。

让我们从我们的第一个实验开始,这样你就可以熟悉它们了。

我们将从由一个根组件和两个子组件“A”和“B”组成的简单组件层次结构开始:

注意:这是Firefox DevTools用于描述事件序列的简单彩色输出。绿色的“呈现”表示组件被呈现(即:调用了它的函数体),蓝色的“useEffect”表示组件内部的效果已经运行。每根原木都有一个彩色标签,以便更容易跟踪。

如您所见,首先,每个组件都是从上到下呈现的,从根组件开始,然后是每个子组件。然后,效果在相反的一侧运行,从下到上。

因为我们的组件相对简单,所以它不能给我们提供渲染器行为的全部情况。让我们为我们的树增加更多的复杂性。

为了更深入地了解渲染过程,我们再向树中添加几个节点:

我们保持与以前相同的行为:从上到下渲染树,并且还遍历每个子对象。正如您所看到的,有一件有趣的事情:节点是按顺序(从“左”到“右”)遍历的。但是,这是Reaction当前实现的行为,不能保证行为,所以无论如何都不要依赖它!(实际上,您为什么需要依赖这个?)

在效果方面,我们可以看到它们是从下到上运行的。可以保证子级特效将在父级特效之前运行,但是不能保证兄弟级特效的顺序会以任何顺序运行(再说一遍,您为什么需要这样做呢?)。

到目前为止,我们分析的所有内容都是第一个渲染行为。我们还没有测试在重新渲染时会发生什么,以及效果的清理操作是如何进行的。

让我们从叶节点(没有子节点的节点)开始。单击节点“3”时,将再次渲染该节点,并且在使用新的道具和状态再次触发它们之前,将清理其先前关联的效果:

React文档说“清理功能在组件从UI中移除之前运行,以防止内存泄漏”,在重新渲染时,任何“前一个效果在执行下一个效果之前都会被清除”。

当您单击具有子节点的节点时,它会为每个子节点调用Render方法,然后继续清理以前的效果,并在每个组件的基础上运行新的效果:

需要注意的一个重要(且有保证的)行为是,Reaction在父级的效果和清理之前运行所有子级的效果和清理。

正如我们之前看到的,在Reaction呈现过程中有一些一致的行为。但是,当前的实现不能保证有关未来行为的任何内容。只有几种记录在案的担保行为可以对担保做出反应,您可以利用这些行为:

当组件更新时,在应用新效果之前,所有以前的效果都会被清除。

我想澄清的是,没有保证并不意味着它一定是以这种方式讨论和决定的。可以在将来更改,但目前,您的组件应该只假设有保证的行为。任何当前行为都可以在未来的Reaction版本中更改,而无需事先通知。

不保证某些行为的好处是你有更多的灵活性。反应纤维就是一个很好的例子。简而言之,Reaction纤程是一个内部实现(因此,您不需要学习使用REACT),它允许暂停工作并稍后继续,为不同类型的工作分配优先级,并在不再需要工作时中止工作。如果您有不同类型的工作需要完成,这是非常有用的。例如:

在经典Reaction的渲染器中,不可能执行此类操作。但是,通过不保证渲染按顺序进行,这是完全可能的,而且以向后兼容的方式进行渲染比没有向后兼容的方式更容易。

我们用Reaction做了真实的实验,了解了它是如何在内部处理渲染的。我们从一个简单的版本开始,然后逐渐增加复杂性,以了解渲染是如何工作的。

我们能够发现Reaction做什么和不做什么保证,所以您可以在将来需要的时候回到这里:-)但是,我认为大多数时候您不需要知道这一点,所以不需要在Reaction中编写代码,但我认为了解这些小细节是很有趣的!-)然而,我认为在大多数情况下您不需要知道这一点,所以不需要在Reaction中编写代码,但是我认为了解这些小细节是很有趣的!

如果您想(真正地)深入了解Reaction的呈现行为,请查看Mark Erikson的文章A(大部分)Complete Guide to Reaction呈现行为。

如果你有任何问题,你可以在推特上联系我,或者给我发一封电子邮件。我很乐意为你做任何事!