防止对特定子组件的重新呈现作出反应。

时间:2022-06-09 16:33:22

I have a react component that conditionally renders several child components. Simplified code is just:

我有一个react组件,它有条件地呈现几个子组件。简化代码是:

render(): {
  const component1 = condition ? renderComponent2() : null;
  const component2 = renderComponent2();

  return (
    <div>
      {component1}
      {component2}
    </div>
  );
}

The problem is that component2 is getting destroyed and re-rendered whenever the condition changes. I'm trying to prevent that and keep the original element around. I tried adding a key to component2 with no luck.

问题是,一旦条件发生变化,component2将被销毁并重新呈现。我试图阻止它并保留原始元素。我试着向component2添加一个键,但运气不佳。

[edit] This is happening even when component1 always exists and I change flag on it to hide it or not with CSS :/

[编辑]即使component1始终存在,并且我更改它的标志以隐藏它或不使用CSS:/时也会发生这种情况

3 个解决方案

#1


2  

Form the example code, your component2 will not be destroyed and re-mounted again. React will run any render and possibly other lifecycle methods, but React will Update the component in the DOM in place.

组成示例代码,您的component2将不会被销毁并重新安装。React将运行任何渲染和其他生命周期方法,但是React将更新DOM中的组件。

Maybe your code is more complicated. Which causes react to think that you are not re-rendering component2, but instead, are trying to render a whole new component. But again, from your example code this is not clear.

也许你的代码更复杂。导致认为不是重新呈现component2,而是试图呈现一个全新的组件。但是,从您的示例代码中,这仍然是不清楚的。

You can find proof of concept codepen here, which does the following:

您可以在这里找到概念代码页的证明,它的作用如下:

  • It renders 2 instances of component2, with a green background.
  • 它呈现了两个组件2的实例,具有绿色背景。
  • Button can (illegally) change background color of the first component to red, outside of react's knowledge.
  • 按钮可以(非法地)将第一个组件的背景颜色改变为红色,在反作用的知识之外。
  • By clicking the button, react will re-render the 2 components.
  • 通过点击按钮,react将重新呈现这两个组件。
  • The background-color remains red, which is proof that react only updates component, and does not destroy.
  • 背景颜色保持为红色,这证明只会更新组件,不会破坏。

React will NOT reset the background color to green, because react thinks (from its virtual DOM) that the background color is unchanged and still green.

React不会将背景颜色重置为绿色,因为React(从它的虚拟DOM)认为背景颜色不变,而且还是绿色的。

UPDATE: The codepen now also contains further proof of how it CAN happen:

更新:codepen现在也包含了它如何发生的进一步证明:

  • if you change the type of HTML returned (from <p> element to <h1> element in proof of concept)
  • 如果您更改返回的HTML的类型(从

    元素到

    元素以证明概念)

  • react will NOT recognize it as the same element, and destroy original and insert a new element.
  • 响应将不会识别它为相同的元素,并销毁原始元素并插入一个新元素。

PS: because your example code creates the component through a method call, any lifecycle methods (such as shouldComponentUpdate) should NOT be applied. Rendering components through methods should only be done for simple components, i.e. react elements. See official docs here:

PS:因为示例代码通过方法调用创建组件,所以不应该应用任何生命周期方法(比如shouldComponentUpdate)。通过方法呈现组件应该只针对简单的组件,即response元素。看官方文档:

A ReactElement is a light, stateless, immutable, virtual representation of a DOM Element.

反应物元素是DOM元素的轻、无状态、不可变的虚拟表示。

#2


1  

Have you tried doing it with shouldComponentUpdate? This is exactly what this function should be used for. Just add it to your component2 and add proper condition inside.

你试过用shouldComponentUpdate做这个吗?这就是这个函数的作用。只需将其添加到component2并在其中添加适当的条件。

#3


0  

If there is a state change in condition the component will re-render itself which means that component2 will be changed too.

如果在条件中有状态更改,则组件将重新呈现自己,这意味着组件2也将被更改。

#1


2  

Form the example code, your component2 will not be destroyed and re-mounted again. React will run any render and possibly other lifecycle methods, but React will Update the component in the DOM in place.

组成示例代码,您的component2将不会被销毁并重新安装。React将运行任何渲染和其他生命周期方法,但是React将更新DOM中的组件。

Maybe your code is more complicated. Which causes react to think that you are not re-rendering component2, but instead, are trying to render a whole new component. But again, from your example code this is not clear.

也许你的代码更复杂。导致认为不是重新呈现component2,而是试图呈现一个全新的组件。但是,从您的示例代码中,这仍然是不清楚的。

You can find proof of concept codepen here, which does the following:

您可以在这里找到概念代码页的证明,它的作用如下:

  • It renders 2 instances of component2, with a green background.
  • 它呈现了两个组件2的实例,具有绿色背景。
  • Button can (illegally) change background color of the first component to red, outside of react's knowledge.
  • 按钮可以(非法地)将第一个组件的背景颜色改变为红色,在反作用的知识之外。
  • By clicking the button, react will re-render the 2 components.
  • 通过点击按钮,react将重新呈现这两个组件。
  • The background-color remains red, which is proof that react only updates component, and does not destroy.
  • 背景颜色保持为红色,这证明只会更新组件,不会破坏。

React will NOT reset the background color to green, because react thinks (from its virtual DOM) that the background color is unchanged and still green.

React不会将背景颜色重置为绿色,因为React(从它的虚拟DOM)认为背景颜色不变,而且还是绿色的。

UPDATE: The codepen now also contains further proof of how it CAN happen:

更新:codepen现在也包含了它如何发生的进一步证明:

  • if you change the type of HTML returned (from <p> element to <h1> element in proof of concept)
  • 如果您更改返回的HTML的类型(从

    元素到

    元素以证明概念)

  • react will NOT recognize it as the same element, and destroy original and insert a new element.
  • 响应将不会识别它为相同的元素,并销毁原始元素并插入一个新元素。

PS: because your example code creates the component through a method call, any lifecycle methods (such as shouldComponentUpdate) should NOT be applied. Rendering components through methods should only be done for simple components, i.e. react elements. See official docs here:

PS:因为示例代码通过方法调用创建组件,所以不应该应用任何生命周期方法(比如shouldComponentUpdate)。通过方法呈现组件应该只针对简单的组件,即response元素。看官方文档:

A ReactElement is a light, stateless, immutable, virtual representation of a DOM Element.

反应物元素是DOM元素的轻、无状态、不可变的虚拟表示。

#2


1  

Have you tried doing it with shouldComponentUpdate? This is exactly what this function should be used for. Just add it to your component2 and add proper condition inside.

你试过用shouldComponentUpdate做这个吗?这就是这个函数的作用。只需将其添加到component2并在其中添加适当的条件。

#3


0  

If there is a state change in condition the component will re-render itself which means that component2 will be changed too.

如果在条件中有状态更改,则组件将重新呈现自己,这意味着组件2也将被更改。