メソッドをバインドする

配下にあるコンポーネントにハンドラを受け渡し、そのハンドラ内でsetStateする場合、あらかじめthis参照を親インスタンスにバインドしておく必要がある。

JavaScriptにおいては関数を変数として渡す際、コンテキスト(this参照)については渡されない為。実行時にaddBookメソッドを実行するのはStockInputインスタンスなので、バインドされてないとStockInput内でstateやaddBookを探しに行き、エラーになってしまう。

class Shelf extends Component {
  constructor(props) {
    super(props);
    this.state = {
      books: [{ id: 0, title: "Never Ending Story" }],
      controlId: 1,
    };
    // コレ!
    this.addBook = this.addBook.bind(this);
  }
  
  addBook(title) {
    const { books, controlId } = this.state;
    books.push({ id: controlId, title });
    this.setState({ books, uniqueId: controlId + 1 });
  }

...

  render() {
    return (
      <StockInput addBook={this.addBook} />
    );
  }
}

bindメソッドを書きたくない時は、アロー関数を使ってthis参照の問題を解決することもできる。propsにメソッドを渡すのではなく、メソッドを使う関数を定義してそれを渡す。

ただし、コンポーネント利用の度に新しく関数を作ることになるので、パフォーマンスを考慮する場合は上記のbindを使うこと。

<StockInput addBook={(title) => { this.addBook(title) }} />