组件消失时不调用 componentWillUnmount 方法
componentWillUnmount method not called when react Component disapears
我无法理解为什么在某些情况下 componentWillUnmount
方法不会被调用,即使我期望的组件已卸载。
更具体地说,就是这个例子。让我们考虑一个带有按钮和 2 个子组件的父组件:Child_Odd 和 Child_Even。如果按钮的点击次数为奇数,则 Child_Odd 被“显示”,否则 Child_Even 被“显示”。
我希望看到 componentWillUnmount
方法在组件“消失”时被调用,但恰恰相反,这并没有发生。 Here a stackblitz reproducing the case(这个 stackblitz 也包括一个类似的情况,其中实际调用了 componentWillUnmount
方法)。
这是相关代码
export class ChildFlipped extends React.Component {
render() {
return (
<div>
{this.props.name} - No of clicks ({this.props.numberOfClicks})
</div>
);
}
}
export class ParentFlips extends React.Component {
constructor(props: any) {
super(props);
this.state = {
clickCounter: 0,
};
}
render() {
return (
<div>
<button
onClick={() => this.updateState()}
>
Click me
</button>
{this.state.clickCounter % 2 ? (
<ChildFlipped
name={"Even"}
numberOfClicks={this.state.clickCounter}
></ChildFlipped>
) : (
<ChildFlipped
name={"Odd"}
numberOfClicks={this.state.clickCounter}
></ChildFlipped>
)}
</div>
);
}
updateState() {
this.setState((prevState, _props) => ({
clickCounter: prevState.clickCounter + 1,
}));
}
}
它没有触发,因为该组件仍处于安装状态。关于对帐,条件表达式
this.state.clickCounter % 2
? <ChildFlipped name={"Even"} numberOfClicks={this.state.clickCounter}/>
: <ChildFlipped name={"Odd"} numberOfClicks={this.state.clickCounter}/>
与
没有区别
<ChildFlipped name={this.state.clickCounter % 2? "Even" : "Odd"}
numberOfClicks={this.state.clickCounter}/>
因为两个子句指的是同一个 ChildFlipped
组件。如果添加密钥,则可以使它们可区分并触发卸载:
his.state.clickCounter % 2
? <ChildFlipped key='even' name={"Even"} numberOfClicks={this.state.clickCounter}/>
: <ChildFlipped key='odd' name={"Odd"} numberOfClicks={this.state.clickCounter}/>
为了试验生命周期方法,我构建了一个 React lifecycle visualizer (StackBlitz) 可能对您有用。
我无法理解为什么在某些情况下 componentWillUnmount
方法不会被调用,即使我期望的组件已卸载。
更具体地说,就是这个例子。让我们考虑一个带有按钮和 2 个子组件的父组件:Child_Odd 和 Child_Even。如果按钮的点击次数为奇数,则 Child_Odd 被“显示”,否则 Child_Even 被“显示”。
我希望看到 componentWillUnmount
方法在组件“消失”时被调用,但恰恰相反,这并没有发生。 Here a stackblitz reproducing the case(这个 stackblitz 也包括一个类似的情况,其中实际调用了 componentWillUnmount
方法)。
这是相关代码
export class ChildFlipped extends React.Component {
render() {
return (
<div>
{this.props.name} - No of clicks ({this.props.numberOfClicks})
</div>
);
}
}
export class ParentFlips extends React.Component {
constructor(props: any) {
super(props);
this.state = {
clickCounter: 0,
};
}
render() {
return (
<div>
<button
onClick={() => this.updateState()}
>
Click me
</button>
{this.state.clickCounter % 2 ? (
<ChildFlipped
name={"Even"}
numberOfClicks={this.state.clickCounter}
></ChildFlipped>
) : (
<ChildFlipped
name={"Odd"}
numberOfClicks={this.state.clickCounter}
></ChildFlipped>
)}
</div>
);
}
updateState() {
this.setState((prevState, _props) => ({
clickCounter: prevState.clickCounter + 1,
}));
}
}
它没有触发,因为该组件仍处于安装状态。关于对帐,条件表达式
this.state.clickCounter % 2
? <ChildFlipped name={"Even"} numberOfClicks={this.state.clickCounter}/>
: <ChildFlipped name={"Odd"} numberOfClicks={this.state.clickCounter}/>
与
没有区别<ChildFlipped name={this.state.clickCounter % 2? "Even" : "Odd"}
numberOfClicks={this.state.clickCounter}/>
因为两个子句指的是同一个 ChildFlipped
组件。如果添加密钥,则可以使它们可区分并触发卸载:
his.state.clickCounter % 2
? <ChildFlipped key='even' name={"Even"} numberOfClicks={this.state.clickCounter}/>
: <ChildFlipped key='odd' name={"Odd"} numberOfClicks={this.state.clickCounter}/>
为了试验生命周期方法,我构建了一个 React lifecycle visualizer (StackBlitz) 可能对您有用。