#はじめに
ReactのsetStateには引数にオブジェクトを渡す方法と関数を渡す方法の2通り存在しますが、この2つはどう違うのか整理してみました。
#setStateについて
setState() はコンポーネントの state オブジェクト更新をスケジュールします。state が更新されると、コンポーネントはそれに再レンダーで応じます。
setState 呼び出しは非同期です。呼び出し直後から this.state が新しい値を反映することを期待しないでください。もし現在の state に基づいた値を計算する必要がある場合は、オブジェクトの代わりに更新関数を渡してください。
#まとめると
- setStateの呼び出しは非同期
- setState()は、引数にオブジェクトが渡された場合に、stateを即時にアップデートすることを保証しない
- 現在のstateに依存する値を更新する場合は、引数にオブジェクトではなく関数を渡す
- 引数に関数を渡すと、その関数内で現在の state の値へアクセスできるようになる
#サンプルコード
App.js
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
counter1: 0,
counter2: 0,
};
this.doAction1 = this.doAction1.bind(this);
this.doAction2 = this.doAction2.bind(this);
}
// 引数にオブジェクトを渡した場合
// これは +1 ずつ増えて正しくない挙動が起きる。
doAction1() {
this.setState({
counter1: this.state.counter1 + 1,
});
this.setState({
counter1: this.state.counter1 + 1,
});
}
// 引数に関数を渡した場合
// これは +2 ずつ増えて正しい処理をする。
// 1つの関数内で state の更新を連続的に行うときは、引数に関数を渡す。
doAction2() {
this.setState(state => ({
counter2: state.counter2 + 1,
}));
this.setState(state => ({
counter2: state.counter2 + 1,
}));
}
render() {
const {counter1, counter2} = this.state;
return (
<div>
<p>引数にオブジェクトを渡した場合:{counter1}</p>
<button onClick={this.doAction1}>Click</button>
<hr />
<p>引数に関数を渡した場合:{counter2}</p>
<button onClick={this.doAction2}>Click</button>
</div>
);
}
}
export default App;
#公式ページに全てが書いてあります