コード
import React, { Component } from "react";
import ReactDOM from "react-dom";
class App extends Component {
constructor(props) {
super(props);
this.state = {
items: null
}
}
componentDidMount() {
const newItems = ['a', 'b', 'c'];
this.setState({
items: newItems
}, () => {
console.log('callback', this.state.items); // ["a", "b", "c"]
})
console.log('まだnullのまま', this.state.items) // null
}
componentWillUpdate(nextProps, nextState) {
console.log('componentWillUpdate', nextState.items); // ["a", "b", "c"]
}
render() {
return (
<h1>Hello World</h1>
)
}
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
Demo => https://codesandbox.io/s/qvzjm1q91q
解説
上記の感じで、配列をstate.countに入れたいのですが、nullのままになってしまいます。
結論から言いますと、正しくstate
の更新自体は出来ています。単に、console.log
を差し込むタイミングが後述の理由により、不適切であるため、null
となってしまうだけの話です。
this.setState({
count: list
});
console.log(this.state.count);//null
this.setState
メソッドは非同期実行されるため、上記のようにthis.setState
メソッドの実行直後に、console.log
で変更後のstate
を確認しようとしても、その段階ではまだ、state
の更新が実行すらされていません。そのため、結果はnull
となります。
単にthis.setState
によってstate
が変更されているかをログ出力して確認したいだけであれば、this.setState
メソッドは第2引数にstate
の変更が完了した後に呼ばれるコールバック関数を渡すことが出来るので、そちらのほうでログ出力してあげると良いかと思います。
もしくは、state
がupdate
された後に呼ばれるライフサイクルメソッド「componentWillUpdate
」内で、変更後のstate
を確認しても良いかもしれません。
参考
Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.
setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.
https://reactjs.org/docs/react-component.html#setstate
補足
componentDidUpdate(prevProps, prevState, snapshot)
https://reactjs.org/docs/react-component.html#componentdidupdate
回答に載せたコードではcomponentWillUpdate
メソッドを使ってますが、React16.3以降ではcomponentWillUpdate
の利用を新規開発で利用するのは非推薦になっているので、代わりにcomponentDidUpdate
でstate
の変更を確認するのが適切と言えます。(上の引用文の中でもsetState
メソッドのコールバックか、componentDidMount
メソッド内で、、、と記載もありますね。)