无法在已卸载的组件上调用setState(或forceUpdate)。反应

zil*_*nas 3 javascript reactjs

Gutentag,伙计们!

卸载组件后,我不断从应用程序中收到此错误消息:

Warning: Can't call setState (or forceUpdate) 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 the componentWillUnmount method.
    in Header (at index.js:27)
Run Code Online (Sandbox Code Playgroud)

现在,这里是Header组件的代码:

class Header extends Component {
  isCancelled = false;
  state = {
    someStateVars: x,
    separateColumns: 'true',
  }

  handleChange = (event) => {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

    if (!this.isCancelled) {
      this.setState({ //######THIS IS LINE 27######
        [name]: value
      });
    }
  }

  handleDisplayChange = (event) => {
    const value = event.target.value;
    const name = 'separateColumns';

    if (!this.isCancelled) {
      this.setState({  
        [name]: value
      }, () => {
        this.props.displayChange();
      });
    }
  }

  serversRefresh = () => {

    if (!this.isCancelled) {
      setTimeout(() => {
        this.setState({refreshed: false});
      }, localStorage.getItem('seconds')*1000); //disable refresh for 15 seconds
    }
  }

  reactivateButton = () => {
    if (!this.isCancelled) this.setState({refreshed: false});
  }

  componentDidMount() {
    if(localStorage.getItem('seconds')>5 && !this.isCancelled){
      this.setState({refreshed: true});
    }
  }

  componentWillUnmount() {
    this.isCancelled = true;
  }
}
Run Code Online (Sandbox Code Playgroud)

当我看到此错误时,我添加了isCancelled变量,该变量在componentWillUnmount()函数中更改为true。

卸载Header组件后,15秒钟后,重新激活serversRefreshbutton时,出现此错误消息。

我该如何解决?

在遇到此问题的另一个组件上,“ isCancelled” var确实起到了帮助,但是在这里我看到它没有任何影响,问题仍然存在。

Lim*_*mbo 5

只需将超时存储在变量中,例如

this.timeout = setTimeout(/* your actions here*/, /* your timeout */)
Run Code Online (Sandbox Code Playgroud)

然后在 componentWillUnmount

componentWillUnmount() {
    clearTimeout(this.timeout)
}
Run Code Online (Sandbox Code Playgroud)

它应该解决您的问题,而不会像那样this.isCancelled。脚。检测组件的安装状态是无操作的,因为即使卸载后它仍会从内存中卸载。

setTimeout返回计时器的ID,以后可以使用该ID取消。clearTimeout如果尚未执行,则通过其ID取消超时。

有关您的案例的更多信息,您可以在这里阅读:为什么isMounted是antipattern

有关MDN上的计时器的更多信息。