LoginSignup
17
10

More than 5 years have passed since last update.

ReactのComponentをClassで書く

Posted at

どこかにあるとは思いますが自分へのメモも兼ねて。

React.createClass => class Hoge extends React.Component

React.createClassの返り値であるConstructorはReact.Componentをprototypeとして持っています。
加えて、引数のobjectのプロパティをマッピングするなどの種々の処理を行っています。
一方、classはprototypeの継承しか行っていないので、種々の処理と同等のことを書かなければなりません。

思いつく書き方

直感で思いつく書き方は以下かと思います。

Todo.js
import React, { Component } from 'react'

class Todo extends Component {
  constructor(props, context, updater) {
    super(props, context, updater)
  }

  getInitialState() {
    return { list: [] }
  }

  addToList(todo) {
    this.state.list.push(todo)
    this.setState({ list: this.state.list })
  }

  render() {
    return (
      <div>
        <h1>Todo</h1>
        <TodoForm addToList={this.addToList} />
        <TodoList list={this.state.list} />
      </div>
    )
  }
}

はい、これだとエラーが出てしまいます。
https://facebook.github.io/react/docs/reusable-components.html#es6-classes
公式にもありますが、getInitialStateは呼ばれないので、constructorでstateの初期化を行う必要があります。
また、他のJavaなどとは違いthisは常にclassをcontextとしないようです。
そのため、this.addToListが呼ばれた時のthisのcontextはTodoではないです。
結果、this.addToListの実行時にstateがnullやらsetStateなんてプロパティは持っていないやら怒られます・・

修正

Todo.js
import React, { Component } from 'react'

class Todo extends Component {
  constructor(props, context, updater) {
    super(props, context, updater)
    // 以下修正点
    this.state = { list: [] }
    this.addToList = this.addToList.bind(this)
  }

  ...,

}

this.stateをconstructor内で初期化してあげて、this.addToListのthisのcontextをclassにbindしてあげます。
以上でエラーはなくなります。

17
10
0

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
17
10