Closed2

React classコンポーネント内のsetState()でエラーが起きた

スジ彫りのマサスジ彫りのマサ

結論:this.setState()が使用されている関数をconstructorでbindしていないことが原因

class InputForm extends React.Component {
  constructor(props) {
    super(props)
    this.state = {value: ''}

    this.handleChange = this.handleChange.bind(this) // ここでthisをbind
    this.handleSubmit = this.handleSubmit.bind(this)
    this.onBlur = this.onBlur.bind(this)
    this.onFocus = this.onFocus.bind(this)
  }

  handleChange(event) {
    this.setState({value: event.target.value})
  }

  handleSubmit(event) {
    alert(this.state.value)
    event.preventDefault();
  }

  onBlur() {
    this.setState({value: 'フォーカス外れたよ!'})
  }
  onFocus() {
    this.setState({value: 'フォーカスされたよ!'})
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          <input
            type="text"
            value={this.state.value}
            onChange={this.handleChange}
            onBlur={this.onBlur}
            onFocus={this.onFocus}
          />
        </label>
      </form>
    )
  }
}

this.handleChange = this.handleChange.bind(this)の辺りの記述を削除すると以下のエラー文が出る。

Cannot read properties of undefined (reading 'setState')

理由:javascript標準(jsx)ではクラスメソッドがデフォルトではバインドされないため。
クラスメソッド内のthisがundefinedになることからthis.setStateが参照できなくなっている。

これを回避するためにconstructorでbindメソッドを利用することで、handleChangeメソッド内のthisの参照先にクラス自身を設定することができる。
(書かない場合、thisの参照先はinputになってしまう?)

スジ彫りのマサスジ彫りのマサ

現在は関数型コンポーネントが主流になりつつあるらしい・・
でもjavascript本来の書き方でも必要になる知識だった!

このスクラップは2022/04/20にクローズされました