Tur*_*ets 12 javascript asynchronous settimeout reactjs react-native
我有一个工作的加载组件,它在加载8秒后取消.这段代码有效,但感觉不对我,我想知道是否有更好的方法来做到这一点.
没有设置this.mounted我得到错误:
警告:只能更新已安装或安装的组件.这通常意味着您在已卸载的组件上调用了setState,replaceState或forceUpdate.这是一个无操作.请检查加载组件的代码.
这让我觉得计时器没有被取消所以继续this.seState.如果我clearTimeout进去,为什么会这样componentWillUnmount?有没有比使用全局更好的方法来解决这个问题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;
Run Code Online (Sandbox Code Playgroud)
T.J*_*der 26
这让我觉得计时器没有被取消
正如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;
Run Code Online (Sandbox Code Playgroud)
但是,如果有比显示更多的逻辑,或者只是个人偏好,是的,单独的功能是好的:
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;
Run Code Online (Sandbox Code Playgroud)
您需要清除使用返回的值setTimeout(见下文).但是,这样做clearTimeout的componentWillUnmount是做正确的方式,我还没有看到任何人做任何不同.
componentDidMount = () => {
this.mounted = true;
this.timeout = this.timer();
};
componentWillUnmount = () => {
this.mounted = false;
clearTimeout(this.timeout);
};
timer = () =>
setTimeout(() => {
(this.mounted && this.setState({ error: true })) || null;
}, 8000);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13808 次 |
| 最近记录: |