概要

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まで来ているということは…。
nextStatethis.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の値が、なぜ変更後の値になっているかということは解決されていないが…。

ここに関してわかる方、教えていただきたいです。

以上です!

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.