Diary

@ssig33

08 Feb 2019 Fri 02:02

React の Hooks で state に Object を使う

const [obj, setObj] = useState({});
const [value, setValue] = useState(1);

みたいなことをしているときに

useEffect(()=>{
  obj.hoge = value;
  setObj(obj);
}, [value]);

としても、コンポーネントはレンダリングされない。なぜかというと、オブジェクトが変わってるかどうかを React は表面的にしか確認しない(これは利点でもある、不必要な変更の走査やレンダリングがはしらない)。

明示的にレンダリングをさせたい場合、以下のようにすればよい。

setObj(Object.assign({}, obj))

新しいオブジェクトをメモリにつくって乗せてしまえば、オブジェクトのなかにあるデータが全く同じものでも、 React はレンダリングをかける。

こういう感じなので Object を Hooks の State に突っ込むのはいい考え方とは言えない(↑のドキュメントにもほかにもいろいろあんま相性よくないからオススメしないよと書かれている)。

全体的に Hooks はマイクロコンポーネントというか、末端のコンポーネントがとにかく強い力を持つべきみたいな世界観で作られているので、親に巨大な state をもって子にバケツリレーするみたいな実装とあまり相性がよくない。

これは React 全体の思想としてそうという話かもしれない。