MeWrite Docs

TypeError: Cannot read property 'setState' of undefined

Reactクラスコンポーネントでthisのコンテキストが失われるエラー

概要

Reactのクラスコンポーネントで、イベントハンドラやコールバック内でthis.setState()を呼び出す際、thisのコンテキストが失われて発生するエラーです。

エラーメッセージ

TypeError: Cannot read property 'setState' of undefined
TypeError: Cannot read properties of undefined (reading 'setState')

原因

  1. thisのバインド忘れ: メソッドをコールバックとして渡すとthisが失われる
  2. クラスメソッドのスコープ: JavaScriptのthisは呼び出し方によって変わる
  3. イベントハンドラ: onClickなどで直接メソッドを渡している

解決策

1. コンストラクタでbind

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
    // コンストラクタでbind
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return <button onClick={this.handleClick}>Click</button>;
  }
}

2. アロー関数でクラスプロパティ(推奨)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class MyComponent extends React.Component {
  state = { count: 0 };

  // アロー関数でthisを自動バインド
  handleClick = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return <button onClick={this.handleClick}>Click</button>;
  }
}

3. レンダリング時にアロー関数でラップ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class MyComponent extends React.Component {
  state = { count: 0 };

  handleClick() {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    // 毎回新しい関数が作られるため非推奨
    return (
      <button onClick={() => this.handleClick()}>
        Click
      </button>
    );
  }
}

4. 関数コンポーネントに移行(推奨)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 関数コンポーネントではthisの問題がない
function MyComponent() {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
  };

  return <button onClick={handleClick}>Click</button>;
}

5. コールバック関数の場合

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class MyComponent extends React.Component {
  state = { data: null };

  // Bad: thisが失われる
  fetchData() {
    fetch('/api/data')
      .then(function(response) {
        this.setState({ data: response }); // Error
      });
  }

  // Good: アロー関数
  fetchData() {
    fetch('/api/data')
      .then((response) => {
        this.setState({ data: response }); // OK
      });
  }
}

6. setTimeout/setIntervalの場合

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Timer extends React.Component {
  state = { seconds: 0 };

  componentDidMount() {
    // Bad
    setInterval(function() {
      this.setState({ seconds: this.state.seconds + 1 }); // Error
    }, 1000);

    // Good
    setInterval(() => {
      this.setState(prev => ({ seconds: prev.seconds + 1 }));
    }, 1000);
  }
}

よくある間違い

  • this.handleClick()(括弧付き)で即時実行してしまう
  • mapのコールバック内でthisを参照する
  • 親から渡されたコールバックを子でthisと一緒に使う

関連エラー

参考リンク

React の他のエラー

最終更新: 2025-12-13