使用setInterval时出现“只能更新已安装或安装的组件”警告

问题描述 投票:1回答:2

我正在开发一个反应原生的应用程序。我需要每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>
            );

        }
reactjs react-native setinterval
2个回答
2
投票

当您导航到新屏幕时,新屏幕将被推到上一个屏幕的顶部。因此,以前的屏幕不会被卸载。这就是你的间隔没有清除的原因。

您可以做的是在执行重定向之前设置变量或状态值,然后在执行另一个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()
}

1
投票

组件卸载时问题在于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
}

这将删除警告错误。

© www.soinside.com 2019 - 2024. All rights reserved.