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也将被更改。