N.X*_*.Xu 5 state children reactjs
在编写 ReactJS 组件时,我发现子组件有时会丢失状态。事实证明,如果子组件使用不同的渲染函数渲染,就会发生这种情况。
IE
父组件有 2 个子渲染函数,根据不同的条件,它要么在主体中渲染子组件,要么在标头中渲染子组件。
...
renderInHeader = () => (<Header><ChildComponent /></Header>);
renderInBody = () => (<Body><ChildComponent /><Body>);
render = () => {
if (somethingHappens) {
return this.renderInHeader();
}
return this.renderInBody();
}
...
Run Code Online (Sandbox Code Playgroud)
这意味着,当 时somethingHappens,它将使用不同的渲染函数来渲染ChildComponent.
那么,ChildComponent就会失去它的状态。(子组件的状态被重置)。
我理解为什么会发生这种情况,实际上我有点惊讶孩子的状态没有更频繁地重置(即每次父级重新渲染该节点时重置)。
然而,处理这个问题的理想解决方案是什么?
避免在子组件中使用状态?(因为不能保证安全?)
key=给ChildComponent一个a ,这样在重新渲染的时候就可以把它当作一个独立的节点了?(不确定是否key可以在映射器之外工作)
使用ref?(不知道是否可以这样工作)
使用 React 16 中的新“Portal”?(还没试过)
注意:我知道我可以使用变量 forHeader和Body,所以只需要一个渲染函数。然而,现实世界的情况可能更复杂,可能有多个子组件分布在不同的区域。
IE
...
renderInBody = () => (
<Body>
<Header>
<ChildComponent1 />
<ChildComponent2 />
</Header>
<ChildComponent3 />
</Body>
);
renderInHeader = () => (
<Header>
<ChildComponent3 />
<ChildComponent1 />
<Body>
<ChildComponent2 />
</Body>
</Header>
);
render = () => {
if (somethingHappens) {
return this.renderInHeader();
}
return this.renderInBody();
}
...
Run Code Online (Sandbox Code Playgroud)
在这里,子组件 1、2、3 并没有真正改变,只是它们的位置和父组件的结构发生了变化。
而且,我不认为将子组件定位策略放入Header和Body组件中是一个好的解决方案。
是否可以保留 ChildComponent 的状态?
ChildComponent不应该是块的一部分,if-else因为它总是被渲染。
render = () => {
const ParentComponent = somethingHappens ? Header : Body;
return (
<ParentComponent>
<ChildComponent />
</ParentComponent>
);
};
Run Code Online (Sandbox Code Playgroud)