search
LoginSignup
2

More than 1 year has passed since last update.

posted at

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

プログラミング開始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
What you can do with signing up
2