gpt4 book ai didi

javascript - 在 componentWillUnmount 中清除超时的更好方法

转载 作者:可可西里 更新时间:2023-11-01 01:57:46 25 4
gpt4 key购买 nike

我有一个正在运行的加载组件,它在加载 8 秒后取消。这段代码有效,但对我来说感觉不对,我想知道是否有更好的方法来做到这一点。

没有设置 this.mounted 我得到错误:

Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op. Please check the code for the Loading component.

这让我觉得计时器没有被取消,所以它继续 this.seState。如果我在 componentWillUnmount 中设置 clearTimeout 为什么会这样?有没有比使用全局 this.mounted 更好的方法来处理这个问题?

class Loading extends Component {
state = {
error: false,
};

componentDidMount = () => {
this.mounted = true;
this.timer();
};

componentWillUnmount = () => {
this.mounted = false;
clearTimeout(this.timer);
};

timer = () =>
setTimeout(() => {
(this.mounted && this.setState({ error: true })) || null;
}, 8000);

render() {
const { showHeader = false } = this.props;
const { error } = this.state;
return (
<View style={backgroundStyle}>
{showHeader && <HeaderShell />}
{!error &&
<View style={loadingHeight}>
<PlatformSpinner size="large" />
</View>}
{error && <Error code="service" />}
</View>
);
}
}

Loading.propTypes = {
showHeader: PropTypes.bool,
};

Loading.defaultProps = {
showHeader: false,
};

export default Loading;

最佳答案

This make me think that the timer is not getting canceled

正如 Pointy 所说,事实并非如此。您正在将一个函数 (this.timer) 传递到clearTimeout。您需要传递 setTimeout 返回值(计时器的句柄),以便您可以使用该句柄来取消它。

在这样一个简单的组件中,我看不到需要 timer 功能,它只会增加复杂性;我只是在 CDM 中设置计时器:

class Loading extends Component {
state = {
error: false,
};

componentDidMount = () => { // ***
// Remember the timer handle // ***
this.timerHandle = setTimeout(() => { // ***
this.setState({ error: true }); // ***
this.timerHandle = 0; // ***
}, 8000); // ***
}; // ***
// ***
componentWillUnmount = () => { // ***
// Is our timer running? // ***
if (this.timerHandle) { // ***
// Yes, clear it // ***
clearTimeout(this.timerHandle); // ***
this.timerHandle = 0; // ***
} // ***
}; // ***

render() {
const { showHeader = false } = this.props;
const { error } = this.state;
return (
<View style={backgroundStyle}>
{showHeader && <HeaderShell />}
{!error &&
<View style={loadingHeight}>
<PlatformSpinner size="large" />
</View>}
{error && <Error code="service" />}
</View>
);
}
}

Loading.propTypes = {
showHeader: PropTypes.bool,
};

Loading.defaultProps = {
showHeader: false,
};

export default Loading;

但是如果有比显示更多的逻辑,或者只是个人喜好,是的,单独的函数是好的:

class Loading extends Component {
state = {
error: false,
};

componentDidMount = () => {
this.setTimer();
};

componentWillUnmount = () => {
this.clearTimer();
};

setTimer = () => {
if (this.timerHandle) {
// Exception?
return;
}
// Remember the timer handle
this.timerHandle = setTimeout(() => {
this.setState({ error: true });
this.timerHandle = 0;
}, 8000);
};

clearTimer = () => {
// Is our timer running?
if (this.timerHandle) {
// Yes, clear it
clearTimeout(this.timerHandle);
this.timerHandle = 0;
}
};

render() {
const { showHeader = false } = this.props;
const { error } = this.state;
return (
<View style={backgroundStyle}>
{showHeader && <HeaderShell />}
{!error &&
<View style={loadingHeight}>
<PlatformSpinner size="large" />
</View>}
{error && <Error code="service" />}
</View>
);
}
}

Loading.propTypes = {
showHeader: PropTypes.bool,
};

Loading.defaultProps = {
showHeader: false,
};

export default Loading;

关于javascript - 在 componentWillUnmount 中清除超时的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45678517/

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