对React基础知识的无知可能会摧毁您

是否想很好地了解使用React时组件会发生什么? 仔细阅读在freeCodeCamp上发表的Ohans Emmanuel文章的翻译。



通常,由于您不了解某些基本知识,因此无法消除某个错误。 出于相同的原因,可能难以掌握更先进的技术。

在本文中,我将尝试讨论React的一些原理,我认为您需要了解这些原理。

我们不会从技术角度分析这些原理。 还有许多其他文章讨论了概念,例如组件属性( props ),状态( state ),上下文( context ),更改组件的状态( setState )等。

我想谈谈您将使用React执行的大多数技术操作的基础。

准备好了吗

隐藏的反应过程


每个人在React中学到的第一件事是如何创建组件。 我相信您也了解了这一点。

例如:

 // functional component function MyComponent() { return <div> My Functional Component </div> } // class based component class MyComponent extends React.Component { render() { return <div> My Class Component </div> } } 

您开出的大多数组件都会向您返回一些元素。

 function MyComponent() { return <span> My Functional Component </span> //span element } class MyComponent extends React.Component { render() { return <div> My Class Component </div> //div element } } 

从内部看,此过程如下所示:大多数组件都返回一棵元素树。

内部评估之后,组件通常返回项目树

另外,您可能还记得,组件是作为根据其属性和state值返回值的函数而工作的。

组件就像带有道具和状态参数的函数

因此,只要属性( props )的值和组件的状态发生变化,就会创建一个新的元素树。

如果属性或状态值更改,则重绘元素树。 结果,出现了一个新的元素树。

如果组件基于类继承,则函数树将返回元素树
 <code>render</code>. <source lang="javascript">class MyComponent extends React.Component { render() { //this function is invoked to return the tree of elements } } 

如果组件正常运行,则其返回值将给出一棵元素树。

 function MyComponent() { // the return value yields the tree of elements return <div> </div> } 

为什么这很重要?

考虑接受prop<MyComponent />组件,如下所示。

 <MyComponent name='Ohans'/> 

渲染此组件将返回元素树。


重绘<MyComponent />后返回的项目树

name值更改时会发生什么?

 <MyComponent name='Quincy'/> 

好吧,新的元素树又回来了!


重绘<MyComponent />和其他道具后返回的新项目树

好啊
React现在有两个不同的树-先前的树和当前的元素树。
在这一点上,React比较两个树以找到更改。


两棵不同的树。 到底发生了什么变化?

该树尚未完全更改,而仅部分更新(在大多数情况下会发生这种情况)。

比较之后,React更新实际的DOM以反映新元素树中的更改。

很简单,不是吗?

比较两棵树以进行更改的过程称为“对帐”。 尽管事实非常复杂 ,您和我仍然可以解析此过程。

React只更新要点,对吗?


在甚至开始使用React之前,您经常听说它有多酷,包括它仅对更新的DOM模型做出重要更改的事实。


来自React Docs :显示更新详细信息的DOM检查器

这就是全部吗?

仅此而已。

但是,请记住:在继续更新DOM之前,React将为各个组件构建一个元素树并进行必要的比较。 简而言之,它将发现前一个项目树与当前项目树之间的差异。

我重复一遍是因为React的新手可能不会注意到应用程序性能的下降,他们认为React只更新DOM中的必要元素。

当然,这是正确的,但是大多数React应用程序的性能问题甚至在DOM更新之前就开始了!

不必要的渲染与视觉更新


即使组件树很小,其渲染也会花费一些时间(至少微不足道)。 组成元素的树越大,渲染所需的时间就越长。

这意味着如果不需要的话,使用React重绘应用程序组件的组件树将是多余的。

让我用一个简单的例子来说明这一点。

想象一个具有组件结构的应用程序,如下图所示。


带有父组件A和子组件B,C和D的应用程序

通用容器组件A获得特定属性。 但是,这样做仅是为了将此属性传递给组件D


父组件A接收一些属性并将其传递给子组件D

现在,当组件A中的属性值更改时, A重绘A所有子元素以计算新的元素树。



当父组件收到新属性时,将重绘每个子组件并返回新树。

因此,即使根本没有更改,组件B也将重新渲染! 他们还没有收到任何新财产!

重新绘制是不必要的渲染。

在此示例中,组件BC不需要重绘,但是React对此没有意识到。

有很多方法可以解决此问题,我在最近的文章如何消除React性能问题中对此进行了描述。

来吧 看看下面的应用程序。


Cardie在行动:)

我称这个应用程序为Carde

当我单击按钮以更改用户的职业时,我可以选择突出显示DOM的更新,如下所示。


使用Chrome DevTools激活更新的可视化显示(闪烁)

现在,我可以看到DOM中已更新的内容。

这是一种标记DOM中需要更新的项目的可视方法。 请注意文本“我是图书馆员”周围的绿色突出显示(“我是图书馆员”。)

当然,这一切都很棒,但是我担心元素的React组件树的初始呈现。

我可以检查一下。


检查React DevTools以突出显示更新的项目。

现在,当我单击此按钮时,可以看到实际上重绘了哪些组件。


注意用户卡周围的绿色突出显示

您是否看到视觉方式在DOM中标记需要更新的元素以及React本身进行的渲染更新有何不同?

React重绘了整个用户地图,并且仅更新了短文本。

这很重要。

结论


我认为现在您对React中的组件发生了什么以及如何进行有了更好的了解。

实际上,发生的事情比我在这里告诉你的要多得多。 但是,这是一个好的开始。

期待创建很棒的应用程序!

学会使用React / Redux吗? 如果是这样,我在Redux上有很多书籍 。 有人说这是他们阅读最好的技术文献

Source: https://habr.com/ru/post/zh-CN426197/


All Articles