文章标题 原创 翻译 转载 文章内容 react native Warning: setState(...): Can only update a mounted or mounting component. 碰到这个问题根据给的提示大概意思是:setState方法仅适用于一个安装好的或者正在安装的组件,出现这个提示通常意味着你在组件卸载之后调用了这个方法。 代码如下,这是一个倒计时组件: ``` /** * Created by tujiaw on 2017/2/19. */ import React, { Component } from 'react'; import { Text, View, StyleSheet, TouchableHighlight, } from 'react-native'; export default class CountDown extends Component { constructor(props) { super(props) this.state = { time: this.props.time ? this.props.time : 60, disabled: true } this._countdown = this._countdown.bind(this) this._onPress = this._onPress.bind(this) } componentDidMount() { this._countdown(); } _onPress(){ if (this.state.disabled) { //nothing } else { this.setState({disabled: true}); this._countdown(); if(this.props.onPress){ this.props.onPress(); } } } _countdown(){ var that = this var timer = function () { var time = that.state.time - 1; that.setState({time: time}); if (time > 0) { setTimeout(timer, 1000) } else { that.setState({disabled: false}); that.setState({time: that.props.time ? that.props.time : 60}); } }; setTimeout(timer, 1000) } render() { var style = [styles.text]; var component; if (this.state.disabled) { component = <View style={styles.container}> <TouchableHighlight> <Text style={styles.disabledText}>{this.props.text}({this.state.time})</Text> </TouchableHighlight> </View> } else { component = <View> <TouchableHighlight style={styles.container} onPress={this._onPress.bind(this)}> <Text style={styles.enableText}>{this.props.endText || '重新获取'}</Text> </TouchableHighlight> </View> } return ( component ) } } var styles = StyleSheet.create({ container: { flexDirection: 'row', width: 100, height: 40, backgroundColor: '#ed7b66', margin: 10, justifyContent: 'center', alignItems: 'center', borderRadius: 4, }, disabledText: { color: '#fff', }, enableText: { color: '#fff', } }); ``` > 可以看到在 _countdown方法中每秒中调用一次timer方法去递减秒数,当组件unmounted之后这个timer并没有停止,所以出现了上面的问题。 **解决办法:** > 将每次setTimeout返回的ID保存起来,在componentWillUnmount方法中clearTimeout 修改后的代码片段如下: ``` componentWillUnmount() { clearTimeout(this.state.timeid) } _countdown(){ var that = this var timer = function () { var time = that.state.time - 1; that.setState({time: time}); if (time > 0) { that.setState({ timeid: setTimeout(timer, 1000) }) } else { that.setState({disabled: false}); that.setState({time: that.props.time ? that.props.time : 60}); } }; this.setState({ timeid: setTimeout(timer, 1000) }) } ``` 文章类别 Python Mobile Android Java Shell Life Database Bug Windows IOS Tools Boost Node.js Mac Product Tips C/C++ Golang Javascript React Qt MQ MongoDB Design Web Linux LLM ChatGPT RAG AI 提交