メソッドをバインドする
配下にあるコンポーネントにハンドラを受け渡し、そのハンドラ内で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) }} />