ReactJS-销毁旧的组件实例并创建新的 [英] ReactJS - Destroy old Component-Instance and create new
问题描述
我有一个可能令人困惑的问题,因为它不符合标准行为,如何反应以及虚拟dom的工作原理,但我还是想知道答案。
I've got a may confusing question because it does not fit standard-behaviour how react and the virtual dom works but i would like to know the answer anyway.
想象一下,我有一个简单的反应组件,称为容器。
容器组件在渲染方法内部有一个 div,其中包含另一个名为 ChildContainer的组件。包围 ChildContainer的 div具有id wrappingDiv。
Imagine i've got a simple react-component which is called "Container". The Container-component has a "div" inside of the render-method which contains another component called "ChildContainer". The "div" which surrounds the "ChildContainer" has the id "wrappingDiv".
示例:
render() {
<Container>
<div id="wrappingDiv">
<ChildContainer/>
</div>
</Container
}
我如何销毁 ChildContainer -component-instance并创建一个全新的组件。这意味着将调用旧实例的 ComponentWillUnmount,并调用新组件的 ComponentDidMount。
How can i destroy the "ChildContainer"-component-instance and create a completly new one. Which mean the "ComponentWillUnmount" of the old instance is called and the "ComponentDidMount" of the new component is called.
我不希望通过更改状态或道具来更新旧组件。
I don't want the old component to update by changing the state or props.
我需要这个行为,因为我们合作伙伴公司的外部库获得了一个可更改dom项目的库,并且在React中,当我更新组件时,我将收到找不到节点异常。
I need this behaviour, because an external library from our partner-company got a libary which change the dom-items and in React i'll get a "Node not found" exception when i Update the component.
推荐答案
如果为组件提供密钥
,然后更改该密钥
重新渲染时,旧的组件实例将被卸载,而新的实例将被装载:
If you give the component a key
, and change that key
when re-rendering, the old component instance will unmount and the new one will mount:
render() {
++this.childKey;
return <Container>
<div id="wrappingDiv">
<ChildContainer key={this.childKey}/>
</div>
</Container>;
}
孩子将有一个新的钥匙$每次,因此React将假定它是列表的一部分,并丢弃旧列表,从而创建新列表。组件中任何导致其重新渲染的状态更改都将迫使子对象卸载并重新创建行为。
The child will have a new key
each time, so React will assume it's part of a list and throw away the old one, creating the new one. Any state change in your component that causes it to re-render will force that unmount-and-recreated behavior on the child.
实时示例:
class Container extends React.Component {
render() {
return <div>{this.props.children}</div>;
}
}
class ChildContainer extends React.Component {
render() {
return <div>The child container</div>;
}
componentDidMount() {
console.log("componentDidMount");
}
componentWillUnmount() {
console.log("componentWillUnmount");
}
}
class Example extends React.Component {
constructor(...args) {
super(...args);
this.childKey = 0;
this.state = {
something: true
};
}
componentDidMount() {
let timer = setInterval(() => {
this.setState(({something}) => ({something: !something}));
}, 1000);
setTimeout(() => {
clearInterval(timer);
timer = 0;
}, 10000);
}
render() {
++this.childKey;
return <Container>
{this.state.something}
<div id="wrappingDiv">
<ChildContainer key={this.childKey}/>
</div>
</Container>;
}
}
ReactDOM.render(
<Example />,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>
话虽如此,对于您的插件潜在问题,可能会有更好的答案。但以上内容解决了实际提出的问题...:-)
Having said that, there may well be a better answer to your underlying issue with the plugin. But the above addresses the question actually asked... :-)
这篇关于ReactJS-销毁旧的组件实例并创建新的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!