概要
reactでsetStateしてもrenderメソッドが動かなくて困った。
先に結論
親のコンポーネントからmap関数でこのコンポーネントをループ処理で作成しているが、key属性を指定してあげると再描画された。
やってみたこと
なんでかなー、と思ってshouldComponentUpdateの中でログを出してみた。
shouldComponentUpdate (nextProps, nextState){
console.log("stateって変わったの?");
const propsDiff = _.isEqual(nextProps, this.props);
const stateDiff = _.isEqual(nextState, this.state);
return !(propsDiff && stateDiff);
}
これをやってみると、一応ログは出せるのでstateの変更は起きている。
再描画されないけどshouldComponentUpdateまで来ているということは…。
nextStateとthis.stateの値が同じ!?、でもそんなことないか、
と思いながらログを出してみると、
shouldComponentUpdate (nextProps, nextState){
console.log("stateって変わったの?");
const propsDiff = _.isEqual(nextProps, this.props);
const stateDiff = _.isEqual(nextState, this.state);
console.log(nextState);
console.log(this.state);
return !(propsDiff && stateDiff);
}
まさかの同じだった。
this.stateは変更前のstateの値が入るはずなのに変更後の値が入って来ていた。
いろいろと調べ物をしている時に、Reactはコンポーネントごとに独自のidみたいなのを割り当て、stateの変更があったら、コンポーネント独自のidと差分のデータをもとに画面を更新する、みたいなことを読んだ。
そういやいままで、map関数を使ってコンポーネントを複製している部分で
bundle.js:4233 Warning: Each child in an array or iterator should have a unique "key" prop.
というエラーが出ていたが、ちゃんとコンポーネントが複製されているし、いっか〜、みたいなノリでこのエラーを無視していた。
しかし、key属性をつけることで、このコンポーネントに独自のidが割り当てられるようになり、stateの変更があった際も、このidのコンポーネントのstateの値が変わった、ということを検知してくれて再描画されるのでは、という仮説を立ててkey属性をつけてみたら、再描画された!shouldComponentUpdateのthis.stateの値も変更前の値になっていたし解決!!
ただ、残る疑問は、なぜ、key属性をつけない場合のshouldComponentUpdateのthis.stateの値が、なぜ変更後の値になっているかということは解決されていないが…。
ここに関してわかる方、教えていただきたいです。