删除所有setState后,“警告:无法对已卸载的组件执行React状态更新”

时间:2019-08-27 23:24:16

标签: reactjs react-native

当我的React本机应用(0.59)渲染Event组件时,会出现有关未安装组件更新的警告。我要做的是注释掉setState组件中的所有Event,但是警告仍然相同。

这是警告消息:

        08-27 13:05:08.713 29432 29510 I ReactNativeJS: 'out of did mount event', { activeEvents: [],
    .....
        08-27 13:05:08.713 29432 29510 I ReactNativeJS:   group_id: 1 }
        08-27 13:05:08.978 29432 29510 E ReactNativeJS: 'Warning: Can\'t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s', 'the componentWillUnmount method', '\n    in NavigationContainer (at App.js:333)'
        08-27 13:05:09.391 29432 29510 I ReactNativeJS: 'event url : ', 'http://192.168.1.4:3000/api/events/active?group_id=1&_device_id=8c9c25711c7d0262&_timezone=America%2FLos_Angeles'
        08-27 13:05:09.423 29432 29510 I ReactNativeJS: 'Events are : ', { type: 'default',
        08-27 13:05:09.423 29432 29510 I ReactNativeJS:   status: 400,
        08-27 13:05:09.423 29432 29510 I ReactNativeJS:   ok: false,
        08-27 13:05:09.423 29432 29510 I ReactNativeJS:   statusText: undefined,
.....
        08-27 13:05:09.423 29432 29510 I ReactNativeJS:   url: 'http://192.168.1.4:3000/api/events/active?group_id=1&_device_id=8c9c25711c7d0262&_timezone=America%2FLos_Angeles',
        08-27 13:05:09.423 29432 29510 I ReactNativeJS:   _bodyInit:

这是Event组件,其中所有setState都被注释掉了:

import React, { Component} from 'react';
import { SectionList, View, Image, Button, StyleSheet, Text, TouchableOpacity, Platform, TouchableHighlight, AppRegistry } from 'react-native';
import {Icon } from "react-native-elements";
import DeviceInfo from 'react-native-device-info';
import helper from "../../lib/helper";
import GLOBAL from "../../lib/global";

export default class Event extends React.Component {

    constructor(props) {
      super(props);
      this._isMounted = true;
      console.log("props in Event : ", this.props);  
      this.state = {
        activeEvents: [],
        user: this.props.myself,
        token: this.props.token,
        group_id: this.props.group_id,
      };

      this._onPress = this._onPress.bind(this);
    };

    async refreshData(result) {
      try {
        let url = `${GLOBAL.BASE_URL}/api/events/active?group_id=${encodeURIComponent(this.state.group_id)}&_device_id=${encodeURIComponent(DeviceInfo.getUniqueID())}&_timezone=${encodeURIComponent(DeviceInfo.getTimezone())}`;
        console.log("event url : ", url);
        //console.log("State in Event : ", this.state);
        let res = await fetch(url, {
          method: "GET",
           headers: {
            'Accept': 'application/json, text/plain',
            'Content-Type': 'application/json',   
            "x-auth-token": result.password,
            "x-auth-secret": result.username,
          }
        });
        console.log("Events are : ", (res));
        //check secret token 
        let secret = res.headers.get("x-auth-secret");
        let token = res.headers.get("x-auth-token");
        res = await res.json();
        if (secret && token && secret !== null && token !== null) {
          if( this._isMounted && await helper.updateJwtToken(secret, token)) {
            //this.setState({token: {password: token, username: secret}});
            result.password = token;
            result.secret = secret;
            //this.props.updateToken(result); //set state token in App.js
          };
        } else if (token === "route to verfi") {
          console.log("res before Verif : ", res);
          this.props.navigation.navigate("Verif1", {cell: res.cell, cell_country_code: res.cell_country_code, existing_user:true});
          return;
        };
        console.log("events after json() : ", res);
        //setState
        let ordered_data = this.eventsByDate(res);
        /* if(this._isMounted) this.setState({
          activeEvents: ordered_data,
        }) */
        console.log("Ordered event data : ", ordered_data);

      } catch (err) {
        console.log("Error in refreshing data ", err);
      };

    };

    async componentDidMount(){
      console.log("Current route name : ", this.props.navigation.state.routeName);
      if (!this.props.group_id) {
        alert("Select a group");
        return;
      };
      //console.log('Did mount event', this.props.myself);
      var result = {};
      try {
        //retrieving token
        let result = this.state.token;
        if (!result) {
          result = await helper.getJwtToken();
           /* if (this._isMounted) this.setState({
             token: result
           });   */
        };

        //console.log("secure store : ", result);
        if (!result) {
          this.props.navigation.navigate("Signup");
          return;
        };

        this.refreshData(result);

        //refresh data after goBack()
        this.willFocusSubscription = this.props.navigation.addListener(
          'willFocus', () => {
            this.refreshData(result);
          }
        );

        //get user
        let myself = this.state.user;
        if (!myself)  {
          myself = await helper._getUser(result.password, result.username);
          /* if (this._isMounted) this.setState({
             user: myself
           });   */
        };

        console.log("out of did mount event", this.state);
      }
      catch (err) {
        console.log("服务器错误(et),请再试一次!", err);
        this.props.navigation.navigate("Event");
        return;

      };

    }

    componentWillUnmount() {
      this._isMounted = false;
      this.willFocusSubscription.remove();
    }

    eventsByDate(events) {
      console.log("Events passed in : ", events);
      if (!events) return [];
      let dates = [];  //unique end_datatime goes here.
      let d1;
      for (i = 0; i < events.length; i++) { 
        d1 = helper.formatDateStr(events[i].event_info["finish_datetime"]);
        console.log('new Date d1 is : ', d1);

        if (!dates) {
            dates.push(d1);
        } else {
            //check if d1 exists in keys
            if (!dates.includes(d1)) {
                dates.push(d1);
            };
        };
      }
      //sort
      if (dates !== []) {
        dates = dates.sort();  //asc
      } else {
        return [];
      };
      console.log("Dates sorted in events : ", dates);
      //fill in for each date
      let dates_ordered = [];
      let obj = {};
      let indx = [];
      for (i=0; i < dates.length; i++) {
        obj = {};
        obj.title = dates[i];
        obj.data = [];
        //ind = [];
        indx = [];
        for (j=events.length-1; j >= 0; j--) {  //indx order DESC so the splice below will work
          if (dates[i] === helper.formatDateStr(events[j].event_info["finish_datetime"])) {
            obj.data.push(events[j]);
            indx.push(j);
          }
        };
        //remove event selected in ind from array events
        console.log("Indx : ", indx);
        indx.forEach(function(ind){
          events.splice(ind, 1);
        });
        console.log("Events left : ", events);
        console.log("obj added : ", obj);
        //insert the obj to the index i
        dates_ordered.splice(i, 0, obj); 
        console.log("dates_ordered : ", dates_ordered);
      }

      console.log("returend dates_ordered : ", dates_ordered);
      return dates_ordered;
    }; 

    _onPress(id) {
      console.log("in _onPress event_id: %d", id);
      this.props.navigation.navigate("Chat", {eventId: id});
    }

    onPressEdit(id) {
      console.log("I am in Edit events", this.state.activeEvents);
      console.log("id : ", id);
      let element = this.state.activeEvents;
      let element1 = element.find((e) => {
        console.log("e.data is ", e.data[0].id);
        return (e.data[0].id == id);
      });
      console.log("event for edit ", element1.data[0]);
      this.props.navigation.navigate("EditEvent", {event: element1.data[0]}); //, myself: this.props.myself, token: this.state.token});
    }

    displayEdit(item) {
      if (this.state.user.role === 'admin' || this.state.user.id === item.created_by_id) {
        return (
          <TouchableOpacity onPress={()=>{this.onPressEdit(item.id)}} >
            <Icon style={styles.image} name='kebab-vertical' size={20} type='octicon' />
          </TouchableOpacity>
          )
      } 
      return "";
    }

    render() {

      return (
         <SectionList
             style={styles.selectionList}
             sections={this.state.activeEvents} 
             renderItem={({item, section, index}) => {return (
                                               <View style={styles.container}>
                                                 <View style={[styles.content, {backgroundColor: colors[index % colors.length]}]}>
                                                   <View style={styles.leftIcon}>
                                                     {/* <Image style={styles.image} source={{}}/> */}
                                                     <TouchableOpacity onPress={() => {this._onPress(item.id)}} >
                                                       <Text style={styles.item} key={item.id}>{item.name}</Text>
                                                     </TouchableOpacity> 
                                                   </View>                                             
                                                   <View>
                                                     {this.displayEdit(item)}
                                                   </View>
                                                 </View>
                                               </View>)}}

             renderSectionHeader={({section}) => <Text style={styles.sectionHeader}>{section.title}</Text>}
             keyExtractor={(item, index) => item + index}
           />
     ); 

警告在componentDidMount之后和方法'refreshData之前生成。定义了_isMounted用于检查Event组件的安装状态。我想知道还有什么会导致未安装组件更新的警告。

更新:   App.js

render() {

    const AppContainer1 = this.bottomTabScreen(); 
    const AppContainer = createAppContainer(AppContainer1)
    return <AppContainer />;  //<<<==line 333 in App.js
  }
};

1 个答案:

答案 0 :(得分:1)

此问题有时会发生。只需按照以下简单步骤操作即可:

1. cd android
2. gradlew clean
3. cd ../
4. react-native run-android

您还可以终止模拟器并擦除数据,然后运行。