[英]prevent component from unmounting when displayed in different parts of the DOM
我的应用程序的布局会根据用户所做的某些选择而发生变化,因此相同的组件会挂在 DOM 中的不同节点下。 不幸的是,React 卸载并重新安装组件。 结果,我的组件丢失了状态已累积。 我试图添加一个key
属性来传达信息,即这是同一个实例,但我得到了相同的结果。 下面显然是一个SSCCE。 每次用户单击按钮时,组件A
都会卸载并重新安装:
class A extends React.Component {
componentWillUnmount = () => {
console.log('map::componentWillUnmount()');
}
componentDidMount = () => {
console.log('map::componentDidMount()');
}
render() {
return (
<div>
this is component A
</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state={i:0};
}
increment = () => {
this.setState({i: this.state.i+1});
}
render() {
console.log('app::render');
if (this.state.i % 2 === 0)
return (
<>
<div>
<div>
<A key={42}/>
</div>
</div>
<button onClick={this.increment}>re-render</button>
</>
);
else return (
<>
<div>
<A key={42}/>
</div>
<button onClick={this.increment}>re-render</button>
</>
)
}
}
只是为了澄清,我的代码除了重现问题之外并没有试图实现任何目标,就像我说的那样,这是一个 SSCCE。 当然,在某些应用程序中,用户可以从“首选项”菜单更改布局,以便组件根据用户的首选项最终位于 DOM 中的不同位置。 我无法想象在这种情况下失去状态是可以接受的。 处理这种情况的正确方法是什么?
这是因为条件渲染返回两个不同的树结构,其中A
的路径不同。
React.Fragment
> div
> div
> A
React.Fragment
> div
> A
想象一下,如果我们通过使用普通的 JS 来模拟 React 来手动安装和卸载,我们将不得不:
<A/>
存储为变量<div/>
( <A/>
也会自动删除)<A/>
附加到外部<div/>
(这实际上不是一个好方法,因为这假设<A/>
一旦安装就永远不需要更新自己,即使道具发生变化)只要有 remove 和 append,就相当于卸载了一个 React 组件,然后再次安装。
代码有点含糊,我无法通过在第一个条件中拥有 2 个<div/>
并且在第二个条件中只有 1 个<div/>
来判断它试图实现什么。 但也许您可以使用三元运算符来有条件地呈现您需要的内容,而将<A/>
单独<A/>
(并且可能是一些 CSS 以使内部<div/>
看起来好像嵌套在另一个<div/>
) . 这样,当<App/>
改变状态时<A/>
不会卸载。
return (
<>
<div>
<A />
{condition ? // where `condition` is a boolean
<div style={{
position: 'absolute'
// and may be other styles to achieve the visual trickery
}}>
{/* your content here */}
</div>
:
null
}
</div>
<button onClick={this.increment}>re-render</button>
</>
)
顺便说一句,他们说 42 是所有问题的答案,但我认为不是这种情况。 将密钥设置为 42 无济于事。 😅
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.