我正在开发一个反应原生的应用程序。我需要每30秒使用fetch检索一些数据。我的代码工作正常,每30秒正确检索一次数据。我的问题是,一旦我重定向到另一个屏幕,我收到以下警告:
警告:只能更新已安装或安装的组件。这通常意味着您在已卸载的组件上调用了setState()。这是一个无操作。请检查xxxxxxxxx组件的代码。
这是我的代码:
dataGet() {
listColumnFetch(this).then(result => {
let ColumnData = result.list;
let ColumnDataArray = Object.keys(ColumnData).map((key) => { return ColumnData[key] });
console.log("serverDataArray:", this.ColumnDataArray);
this.setState({
ColumnData,
ColumnDataArray,
isLoading: false,
CurrentData: new Date(),
});
});
}
componentDidMount() {
this.dataGet();
this.interval = setInterval(() => this.dataGet(), 30000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
虽然我在clearInterval
中做了componentWillUnmount
,但是应用程序在其他页面中每30秒发出一次警告。似乎计时器没有停止,它在后台。你能帮我解决这个问题吗?谢谢你提前。
更新:此处我尝试重定向到另一个页面。这是我的其余代码:
onPressNew() {
this.props.navigation.navigate('RechargeElectricCar', {user: this.state.user, activeSection: 'NoChargeInProgress_2a'});
}
render() {
if (this.state.isLoading) {
return(
<View>
<ActivityIndicator size="large" color="#79b729"/>
</View>
);
}
return (
<View style={styles.container} ref="park-progress-ref">
<View style={styles.titleContainer}>
<Text style={styles.itemBold}>{I18n.t('queste_ricariche')}</Text>
</View>
<View style={ styles.rowSep } />
<View style={ styles.listContainer } >
<FlatList
ItemSeparatorComponent={ () => <View style={ styles.rowSep } /> }
horizontal={false}
data={this.state.result}
renderItem={
({item}) => (
<View style={styles.containerrow}>
<View style={styles.viewPark}>
<Text style={styles.itemBold}> {I18n.t('Data_e_ora_inizio')}: <Text style={styles.itemNormal}>{item.start}</Text></Text>
<Text style={styles.itemBold}> {I18n.t('Data_e_ora_termine')}: <Text style={styles.itemNormal}>{item.end}</Text></Text>
<Text style={styles.itemBold}> {I18n.t('Energia')}: <Text style={styles.itemNormal}>{item.energy_delivered} KWh</Text></Text>
<Text style={styles.itemBold}> {I18n.t('Colonna')}: <Text style={styles.itemNormal}>{item.column_id}</Text></Text>
<Text style={styles.itemBold}> {I18n.t('Costo_della_ricarica')}: <Text style={styles.itemNormal}>€ {item.amount}</Text></Text>
<Text style={styles.itemBold}> {I18n.t('Aggiornamento_del')}: <Text style={styles.itemNormal}>{this.currentTime()}</Text></Text>
</View>
<View style={styles.rowCenter}>
<Button label={I18n.t('Via_questa_ricarica')} color={defStyleValues.RechargeElectricCar} onPress={ () => {console.log("MARCO log"); this.onPressTopUp(item.column_id)} } />
</View>
</View>
)
}
keyExtractor={item => item.id}
/>
</View>
<View style={ styles.rowSep } />
<View style={ styles.buttonContainer } >
<FadeInView
duration={2000}
style={{ alignItems: 'center' }}>
<ButtonIcon_White onPress={ () => { this.onPressNew() }} label={I18n.t('Nuova_ricarica')} />
</FadeInView>
</View>
</View>
);
}
当您导航到新屏幕时,新屏幕将被推到上一个屏幕的顶部。因此,以前的屏幕不会被卸载。这就是你的间隔没有清除的原因。
您可以做的是在执行重定向之前设置变量或状态值,然后在执行另一个setState
之前检查该值。
另一件需要考虑的事情是在返回上一个屏幕时更改值。要处理它你可以将一个函数作为参数传递到下一个屏幕,并在下一个屏幕的componentWillUnmount
下面运行它。
例
onPressNew() {
// set stop value before navigating
this.setState({ stop: true }, () => {
this.props.navigation.navigate('RechargeElectricCar', {
user: this.state.user,
activeSection: 'NoChargeInProgress_2a',
onBack: this.onBack // Added this param for changing state to false
});
});
}
onBack = () => {
this.setState({stop: false});
}
//....
dataGet() {
// check stop value before fetching
if(this.state.stop !== true) {
listColumnFetch(this).then(result => {
let ColumnData = result.list;
let ColumnDataArray = Object.keys(ColumnData).map((key) => { return ColumnData[key] });
console.log("serverDataArray:", this.ColumnDataArray);
this.setState({
ColumnData,
ColumnDataArray,
isLoading: false,
CurrentData: new Date(),
});
});
}
}
在下一个屏幕上(RechargeElectricCar屏幕)
componentWillUnmount() {
this.props.navigation.state.params.onBack()
}
组件卸载时问题在于setState设置状态。
componentDidMount() {
this.isMountedComp = true
}
dataGet() {
listColumnFetch(this).then(result => {
let ColumnData = result.list;
let ColumnDataArray = Object.keys(ColumnData).map((key) => { return ColumnData[key] });
console.log("serverDataArray:", this.ColumnDataArray);
if(this.isMountedComp) {
this.setState({
ColumnData,
ColumnDataArray,
isLoading: false,
CurrentData: new Date(),
});
});
}
}
componentWillUnMount() {
clearInterval(this.interval);
this.isMountedComp = false
}
这将删除警告错误。