const {position,setPosition}= React.useState({
x: 0, y: 0
});
上のようなオブジェクト形式でstateにつっこんでいて値の更新をしたい時は
setPosition({ ...position, x: position.x + 1 });
//position.x:1 position.xy:0
上記のように
1.state内のオブジェクトをスプレッド構文(…)でコピーして展開(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax)
2.setState内で更新したい値に変更をかけて上書き保存
をおこなう。
React内部で両方の値が同一のオブジェクトか(メモリ内の同じオブジェクトを参照しているか)どうかで更新するかを判定している。
そのためオブジェクトの列挙可能なプロパティを、新しいオブジェクトにコピーしてくれるスプレット構文を用いて更新することで別のObjectに更新されたものとして再レンダリングが走る。
//OK⭕️
let position= {
x: 0, y: 0
};
let spread_obj ={ ...position, x: position.x};
console.log(Object.is(position, spread_obj));//falseなのでreact内で別の値として認識される
//NG❌
position.x= position.x+ 1;
setPosition(position);
//同じpositionオブジェクトの参照をしていて内部の値が変わってないと認識される=再レンダリングされない
配列であっても同じようにスプレット構文を用いて更新できる。(ただしコピーの深さが一段階のため多次元配列[[],[]]は注意)