javascript - 为什么 React 会丢弃整个 DOM 子树并从头开始重新创建它?

标签 javascript reactjs

有两个助手可用于在渲染时添加内容:

  ...

  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 总是丢弃整个子树并从头开始重新创建它,如下所示:

subtree is discarded and recreated

The demo

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

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

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

请注意,助手可以来自 Prop ,例如(渲染 Prop 模式)。

最佳答案

这将取决于 DisplayA 的定义范围。功能组件通常应定义在文件的顶层。在您的演示中,DisplayA 是在 Apprender 内部创建的组件,因此每次 App 都会渲染一个创建新的功能组件,而不是同一组件的新调用。

要解决此问题,请在文件中将 DisplayA 设置为顶层并将 props 传递给它。

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

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

第二种方法不会创建一个传递给 React 进行协调的组件,而是一个在渲染时调用的函数,并将包含的元素放入该组件的渲染中。

关于javascript - 为什么 React 会丢弃整个 DOM 子树并从头开始重新创建它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58507656/

相关文章:

javascript - React如何更新状态?

javascript - 如何在没有空回调的情况下测试多个调用

javascript - AngularJS:从 ng-repeat 中删除 $watch

javascript - react native : Getting data from one class to another

javascript - "this.setState is not a function"在嵌套的 addEventListener 函数中使用 setState 时

javascript - 如何让 div 滚动到其容器的底部,然后在 React 中完成后向上滚动?

javascript - 在 ReactJs 中实现 ButtonToggleGroupComponent

javascript - 类型错误 : Converting circular structure to JSON when sending array via express

javascript - React JS - IMG onclick 事件后无法更新文本

javascript - 带有后退按钮的 Jquery 移动更改页面不起作用