当使用不同的函数渲染时,ReactJS 子组件会丢失其状态

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”?(还没试过)


注意:我知道我可以使用变量 forHeaderBody,所以只需要一个渲染函数。然而,现实世界的情况可能更复杂,可能有多个子组件分布在不同的区域。

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 并没有真正改变,只是它们的位置和父组件的结构发生了变化。

而且,我不认为将子组件定位策略放入HeaderBody组件中是一个好的解决方案。

是否可以保留 ChildComponent 的状态?

Abd*_*UMI 0

ChildComponent不应该是块的一部分,if-else因为它总是被渲染。

render = () => {
  const ParentComponent = somethingHappens ? Header : Body;
  return (
    <ParentComponent>
      <ChildComponent />
    </ParentComponent>
  );
};
Run Code Online (Sandbox Code Playgroud)