简体   繁体   中英

React Native: best practice to setInterval and Promises with setState in it

I'm currently battling this "cannot setState() or forceUpdate() on unmounted component error" and having a hard time tracing which async operation the error is from. I'm suspecting it's because of the setInterval I use to add seconds to display current time. Here's what I have in componentDidMount , componentWillUpdate and componentWillUnmount that are responsible for managing the time display:

componentDidMount() {
    this.mounted = true;

    //listener to identify whether app is active/inactive
    AppState.addEventListener('change', this.handleAppStateChange.bind(this));

    //get user's intranet schedule
    this.props.actionsMain.getSchedule(this.props.staff.staffID);

    this.getLocation();
    //After the first location received, re-check every 20 seconds
    this.locationInterval = setInterval(() => {
      this.getLocation();
    }, 20000);
  }

componentDidUpdate() {
    //when we just received server time, parse and set the time to state, then set the interval timer
    if (this.props.scheduleReceived && this.state.time[0] === null) {
      let time = this.props.schedule['time_server'].split(':'),
        hh = parseInt(time[0]) + this.props.location.zone,
        mm = parseInt(time[1]),
        ss = parseInt(time[2]);

      if (this.mounted) {
        this.setState({ time: [hh, mm, ss] });

        this.serverTimeInterval = setInterval(() => {
          let { time } = this.state, hh = time[0], mm = time[1], ss = time[2];

          //add second and adjust time
          ss += 1;
          if (ss >= 60) {
            ss -= 60;
            mm += 1;

            if (mm >= 60) {
              mm -= 60;
              hh += 1;

              if (hh >= 24)
                hh -= 24;
            }
          }

          if (this.mounted)
            this.setState({ time: [hh, mm, ss] })
        }, 1000)
      }
    }
  }

componentWillUnmount() {
    //Remove all timer events
    clearInterval(this.serverTimeInterval);
    clearInterval(this.locationInterval);

    //Remove listener
    AppState.removeEventListener('change', this.handleAppStateChange.bind(this));

    this.mounted = false;
  }

Can anyone point out what I have done wrong here and if even what I'm doing is a good practice at all?

Also on the same note, my second suspicion would comes from fetch location promise that was executed from the setInterval() and returned to an unmounted component. If there's any rule of thumb that I can follow on how I can make sure that setInterval, setState and Promises work harmoniously that would be awesome!

Thanks in advance!

您永远不要在componentDidUpdate中调用setState,这将导致无限循环

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM