我有一个组件,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}
有没有理智的解决方法?
答案 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。