Reactjs &引用;只能更新已安装或正在安装的部件”;使用设置间隔时出现警告

Reactjs &引用;只能更新已安装或正在安装的部件”;使用设置间隔时出现警告,reactjs,react-native,setinterval,Reactjs,React Native,Setinterval,我正在用React Native开发一个应用程序。我需要每隔30秒使用fetch检索一些数据。我的代码工作正常,每30秒正确检索一次数据。我的问题是,一旦我重定向到另一个屏幕,我就会收到以下警告: 警告:只能更新已安装或正在安装的组件。这通常 表示您在未安装的组件上调用了setState()。这是一个 否操作。请检查xxxxxxxxx组件的代码 这是我的密码: dataGet() { listColumnFetch(this).then(result => { let

我正在用React Native开发一个应用程序。我需要每隔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);
  }
尽管我在
componentWillUnmount
中执行了
clearInterval
,但该应用程序在其他页面中每隔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>
            );

        }
onPressNew(){
this.props.navigation.navigate('RechargeElectricCar',{user:this.state.user,activeSection:'NoChargeInProgress_2a');
}
render(){
if(此.state.isLoading){
返回(
);
}
返回(
{I18n.t('queste_ricariche')}
}
水平={false}
数据={this.state.result}
伦德雷特={
({item})=>(
{I18n.t('Data_e_ora_inazio')}:{item.start}
{I18n.t('Data_e_ora_termine')}:{item.end}
{I18n.t('Energia')}:{item.energy_交付}KWh
{I18n.t('Colonna')}:{item.column_id}
{I18n.t('Costo_della_ricarica')}:€{项目金额}
{I18n.t('Aggiornamento_del')}:{this.currentTime()}
{console.log(“MARCO log”);this.onPressTopUp(item.column_id)}/>
)
}
keyExtractor={item=>item.id}
/>
{this.onPressNew()}}label={I18n.t('Nuova_ricarica')}/>
);
}

问题在于组件卸载后的设置状态

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
}

这将删除警告错误。

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

您可以做的是在执行重定向之前设置变量或状态值,然后在执行另一个
setState
之前检查该值

另一个要考虑的是当你回到前一个屏幕时改变值。要处理这个问题,您可以将函数作为参数传递给下一个屏幕,并在下一个屏幕的
组件将卸载时运行它,如下所示

示例

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(),
      });
    });
  }
}
在下一个屏幕(电动汽车屏幕)


你是在按另一个屏幕还是弹出屏幕?在
组件上执行
控制台。记录
将卸载
并查看它是否记录。重定向部分在哪里?在
clearInterval中有什么?它解决了什么问题?谢谢你的回答,我会在几秒钟内更新你的问题。@bennygenel:谢谢你的回答,真奇怪!它没有显示控制台日志。这意味着它没有被执行!你知道吗?谢谢你的回答。但它仍然存在。你有更多的信息吗?你有更多的设置说明你的部件在哪里吗?是的,我有。但每当我添加setinterval时,就会出现此警告。我更新了这个问题。它们在dataGet()函数中。谢谢你的回答,这意味着componentWillUnmount()从未执行过,对吗?@Reza如果你执行
this.props.navigation.goBack()
它会执行。非常感谢,我投了赞成票并把它作为答案。
componentWillUnmount() {
  this.props.navigation.state.params.onBack()
}