LoginSignup
2

More than 3 years have passed since last update.

ReactでCan't perform a React state update on an unmounted component.の原因と解決

Posted at

プログラミング開始7ヶ月目の者です。

ReactのクラスコンポーネントのcomponentDidMountについてです。

メソッド内でsetTimeoutの記述をしました。

  // 表示される毎に実行
  componentDidMount() {
    setTimeout(() => {
      this.setState({ isVisible: !this.state.isVisible });
    }, 1000);
  }

それでsetTimeoutで値が切り替わる前に別のLink(Router)に飛ぶとエラーが出ました。

エラー

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 the componentWillUnmount method.

原因

componentDidMountしたのにunmountedされたまま、別のLinkに移った為です。
「マウントされないcomponentでstateを更新しようとしています。componentWillUnmountでキャンセルしてね。」

解決

componentWillUnmount用に変数とメソッドを追加し代入する。
これで別のページに移ったときにcomponentWillUnmountでキャンセルされます。

  // unmount用の変数
  handle;

  // 変数に代入
  componentDidMount() {
    this.handle = setTimeout(() => {
      this.setState({ isVisible: !this.state.isVisible });
    }, 1000);
  }
  // unmount用メソッドを追加 引数に変数を入れる。
  componentWillUnmount() {
   clearTimeout(this.handle);
  }

修正サンプル。
const props = {
  visible: {
    opacity: 1,
  },
  hidden: {
    opacity: 0,
  },
}
const Box = posed.div(props)

export default class Can extends React.Component {

  handle;

  state = {
    isVisible: false,
  };
  // mount
  componentDidMount() {
    this.handle = setTimeout(() => {
      this.setState({ isVisible: !this.state.isVisible });
    }, 1000);
  }
  // unmount
  componentWillUnmount() {
   clearTimeout(this.handle);
  }
  render() {
    return (
      <Box pose={this.state.isVisible ? 'visible' : 'hidden'}>出現</Box>
    );
  }
}

参考

エラーで悩んでいた時に見つけた 記事 です。

以上です!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2