コード
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メソッド内で、、、と記載もありますね。)