gpt4 book ai didi

javascript - React 单击以卸载组件消息

转载 作者:行者123 更新时间:2023-11-30 20:10:10 24 4
gpt4 key购买 nike

在卸载组件时收到此消息:

Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method. in NumberButton (at App.js:37)

我有一个父对象,它有一个包含按钮列表的数组。每个按钮都有一个 onclick 调用父级,父级将从列表中删除单击的按钮。

问题是该函数的目的是单击以从根本上破坏自身。该方法的完成方式不需要需要取消绑定(bind)的显式绑定(bind),因此我不认为组件中存在内存泄漏。

请告知我为什么会收到此消息、我可以做什么以及它是否是误报消息。

父类:

class PanelDiv extends Component
{
constructor(props) {
super(props);
this.state = {items: [0]};
this.addChild = this.addChild.bind(this);
this.buttonClickHandler = this.buttonClickHandler.bind(this);
}

render()
{
return (<div id="DivBackground" onLoad={() => this.PanelLoaded()} style={{width: '100%', height: '100%', backgroundImage: "url(" + BackgroundImage + ")", backgroundSize: "cover"}}>
{
this.state.items.map((item) => (
<NumberButton key={"Nb" + item.toString()} parentClickHandler={this.buttonClickHandler} id={"Nb" + item.toString()} />
))
}
</div>);
}

componentDidMount()
{
setInterval(this.addChild, Settings.COMPONENT_ADD_INTERVAL);
}

buttonClickHandler(clientId) {

this.setState((previousState, currentProps) => ({
items: previousState.items.filter(element => {

return element.toString() !== clientId.substring(2)

}
//console.log("Matching Element: ")
)
}));
}

componentWillUnmount() {

}

addChild()
{

this.setState((previousState, currentProps) => {

if (previousState.items.length == 0)
return {items:[0]};
else
return {items: previousState.items.concat([previousState.items[previousState.items.length-1]+1])};
});
}
}

子类:

class NumberButton extends Component
{

constructor(props) {
super(props);
var varLeft = (0 + (Math.random() * (90-0))).toString() + '%';
var timeoutValue = Settings.BUTTON_SPEED_MIN + (Math.random() * (Settings.BUTTON_SPEED_MAX-Settings.BUTTON_SPEED_MIN));
var numberValue = Math.round(Math.random() * (Settings.MAX_NUMBER));


this.state = { clientId: props.id, wavePath: Waves[numberValue], left: varLeft, top: 0, counter: "Hello", timeoutValue: timeoutValue, numberValue: numberValue };
}


updateCount() {

this.setState((prevState, props) => {
return { top: prevState.top + 1 }
});
setTimeout(()=> this.updateCount(), this.state.timeoutValue)

}

componentDidMount()
{
this.updateCount();
//this.buttonClicked = this.buttonClicked.bind(this);
}

componentWillUnmount() {

}

render()
{
return (
<button id={this.state.clientId} onClick={() => this.buttonClicked()} style={{color: "white", fontSize: Settings.BUTTON_FONT_SIZE, fontFamily: "Verdana", border: "none", backgroundColor: "Transparent", backgroundSize: "cover", backgroundImage: "url(" + CoconutImage + ")", position: "absolute", left: this.state.left, top: this.state.top, width: Settings.BUTTON_WIDTH_AND_HEIGHT, height: Settings.BUTTON_WIDTH_AND_HEIGHT}}>
{this.state.numberValue}
</button>

);
}


buttonClicked()
{
var audio = new Audio(this.state.wavePath);
audio.play();
this.props.parentClickHandler(this.state.clientId);
}
}

This是我最初的引用问题。

最佳答案

无论何时执行 setTimeout 或 setInterval,请确保在 componentWillUnMount 生命周期方法中清除它们。像下面这样的东西

 componentDidMount() {
this.addChildTimer = setInterval(this.addChild, Settings.COMPONENT_ADD_INTERVAL);
}

componentWillUnMount(){
clearInterval(this.addChildTimer);
}

componentWillUnmount is meant to eliminate the interval that was set earlier when it mounted

像你的子组件一样明智

 updateCount() {
this.setState((prevState, props) => {
return { top: prevState.top + 1 }
});
this.updateCountTimer = setTimeout(()=> this.updateCount(), this.state.timeoutValue)
}

componentWillUnMount(){
clearTimeout(this.updateCountTimer);
}

注意:避免在 setInterval 中执行 setState

关于javascript - React 单击以卸载组件消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52489325/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com