React:在父母重新渲染时阻止重新安装

时间:2016-03-23 18:53:02

标签: javascript reactjs

我有一个组件,Split,需要两个孩子。第一个孩子将显示在屏幕的左侧。右手边的第二个孩子。如果屏幕宽度低于某个点,则只显示右侧,左侧将从DOM中删除。

示例子项可以是Sidebar组件和Content组件。对于移动设备,我不想显示菜单,但有一个特殊的移动菜单,我会弹出。

我的问题是:如何删除Sidebar组件而不卸载&还要重新安装Content组件吗?

我的Content组件在componentDidMount上提取数据,我不希望它再次重新提取或重新安装(从而丢弃用户输入)。

基本上我有这样的事情:

<Split>
  <Sidebar/>
  <Content/>
</Split>

Split的渲染方法看起来像这样:

let children;
let firstChild = this.props.children[0];
let lastChild = this.props.children.pop();
if (this.state.responsive === 'singleColumn') {
  children = (
    <div>
      <div style={{display: 'none'}}>{firstChild}</div>
      {lastChild}
    </div>
  );
} else {
  children = (
    <div>
      {firstChild}
      {lastChild}
    </div>
  );
}

return (
  <div>
    {children}
  </div>
);

即使{lastChild}总是呈现,无论如何,每次分割都必须重新渲染时,它仍然会被卸载并重新安装!

即使有一个看起来像这样的渲染:

return (
  <div>
    {this.props.children.pop()}
  </div>
);

导致最后一个孩子(永远不会改变)被卸下&amp;在呈现之前重新安装。

如果我改为修改Split并将总是在DOM中的组件作为属性传递给:{/ p>

<Split staticComponent={<Content />}>
  <Sidebar />
</Split>

它工作正常。那么为什么当我刚刚弹出最后一个孩子时,这个{this.props.children.pop()}而不是{this.props.staticComponent}

有没有理智的解决方法?

3 个答案:

答案 0 :(得分:2)

终于设法解决了这个问题!我重新写了Split的渲染,看起来像这样:

let left;
if (this.state.responsive !== 'singleColumn') {
  left = this.props.children.slice(0, -1);
}

return (
  <div ref="split" className={classes.join(' ')}>
    {left}
    {this.props.children[this.props.children.length-1]}
  </div>
);

这样,最后一个孩子总是被渲染。显然pop()没有工作,因为那时我修改了引发奇怪行为的原始儿童数组。

答案 1 :(得分:0)

这可以使用生命周期方法完成:shouldComponentUpdate:

shouldComponentUpdate: function(nextProps, nextState) {
  return this.props.value !== nextProps.value;
}

如果内部逻辑返回false,则组件不会更新。

查看文档:{​​{3}}

答案 2 :(得分:0)

您可以在组件的生命周期中使用shouldComponentUpdate函数。如果它返回false,则根据文档

  

如果shouldComponentUpdate返回false,则将完全跳过render()直到下一个状态更改。此外,不会调用componentWillUpdate和componentDidUpdate。