为什么React会丢弃整个DOM子树并从头开始重新创建它? [英] Why does React discard the entire DOM subtree and recreate it from scratch?

查看:29
本文介绍了为什么React会丢弃整个DOM子树并从头开始重新创建它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有两个可以在渲染时添加内容的助手:

There are two helpers that can be used to add content while rendering:

  ...

  const DisplayA = () => <div className={'containerA'}>
    <button onClick={handleToggleA}>{"A toggled: " + toggledA.toString()}</button>
  </div>

  const displayB = () => <div className={'containerB'}>
    <button onClick={handleToggleB}>{"B toggled: " + toggledB.toString()}</button>
  </div>

  return (
    <>
      <DisplayA />
      { displayB() }
    </>
  );

  ...

问题在于,在第一个帮助程序中,React总是丢弃整个子树,然后从头开始再次创建它,如此处所示:

The problem is that in the first helper, React always discards the entire subtree and creates it again from scratch, as can be seen here:

演示

我知道,第一种方法是React.createElement的语法糖,因此每个渲染都会创建一个新组件.但是,第二种方式是,每个渲染也创建一个独特的箭头函数.

I know, the first way is syntax sugar for React.createElement so a new component is created each render. However, the second way, a distinct arrow function is created each render too.

  1. 为什么React不知道如何以第一种方式重用子树,但是知道第二种方式?内幕发生了什么?

我们如何发现DOM子树何时被丢弃并在每个渲染中重新创建?假设不应该创建内联组件并且仅使用内联函数就足够了吗?

How can we spot when the DOM subtree is discarded and recreated each render? Is it enough to assume that one should not create inline components, and use inline functions only?

请注意,助手可以来自道具(例如,渲染道具模式).

Notice, that helpers can come from props, for example (render props pattern).

推荐答案

这将取决于定义 DisplayA 的范围.功能组件通常应在文件的顶层定义.在您的演示中, DisplayA 是一个在 App render 中创建的组件,因此,每次 App 呈现一个创建了新的功能组件,而不是相同组件的新调用.

This will depend in which scope DisplayA is defined. Functional components should usually be defined at the top level of a file. In your demo DisplayA is a component that is created inside the render of App, so every time App renders a new functional component is created, not a new invocation of the same component.

要解决此问题,请在文件中将 DisplayA 置于顶层,并将道具传递给文件.

To resolve this make DisplayA top level in the file and pass props through to it.

const DisplayA = ({handleToggle, toggled}) => <div className={'containerA'}>
  <button onClick={handleToggle}>{"A toggled: " + toggled.toString()} </button>
</div>

const App = () => {
  ...
  return <>
    <DisplayA handleToggle={() => {...}} toggle={...} />
  </>
}

第二种方法不创建传递对协调作出反应的组件,而是在渲染时调用该函数并将所包含的元素放入此组件的渲染中的函数.

The second approach does not create a component which is passed to react for reconciliation, but is a function which is invoked while rendering and puts the contained elements into the rendering of this component.

这篇关于为什么React会丢弃整个DOM子树并从头开始重新创建它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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