私はいつも、ReactのuseStateでオブジェクト(連想配列)の更新に手を焼いています。
どうやるんだっけ?
ということで、この記事に更新のやり方を残しておきます。
useStateでオブジェクトを更新する方法
オブジェクトの一部だけ変更
const [state, setState] = useState({ id: 1, name: 'foo' });
const updateState = () => {
setState((prevState) => ({ ...prevState, name: 'bar' }));
// { id: 1, name: 'bar' }
};
前の状態(ここではprevState)を関数として渡して、オブジェクトの一部を書き換えています。
…prevStateはスプレッド構文といって、オブジェクトの要素を展開します。
name: ‘bar’は上書きされるので、結果としてstateは{ id: 1, name: ‘bar’ }で更新されます。
配列の更新
配列に要素を追加
const [state, setState] = useState(['foo', 'bar']);
const addState = () => {
setState((prevState) => ([ ...prevState, 'baz' ]));
// ['foo', 'bar', 'baz']
};
例によって、…prevStateで展開してから要素を追加します。
配列の順番を入れ替えれば、先頭にも追加できました。
setState((prevState) => (['baz', ...prevState]));
配列の中間に要素を追加したいときは、spliceを使うと良いかも。
setState((prevState) => {
const arr = [...prevState];
arr.splice(1, 0, 'baz');
return arr;
});
配列の特定の要素を削除
const [state, setState] = useState(['foo', 'bar']);
const deleteState = () => {
setState((prevState) => prevState.filter((value) => value !== 'bar'));
// ['foo']
};
filterを使用して条件文で要素を絞り込んだ配列を返せば、不要な要素を削除できます。
配列の特定の要素を変更
const [state, setState] = useState(['foo', 'bar']);
const updateState = () => {
setState((prevState) =>
prevState.map((value) => (value === 'bar' ? 'new' : value))
);
// ['foo', 'new']
};
mapを使用して、変更したい要素だけ書き換えた配列を返しています。三項演算子を使ってあげると良い感じにできます。
値ではなく、indexで指定するパターンでもOKです。
prevState.map((value, index) => (index === 1 ? 'new' : value))
もしオブジェクトが配列になっていたら
ちょっと面倒ですが、配列の要素がオブジェクトになるだけです。
const [state, setState] = useState([
{ id: 1, name: 'foo' },
{ id: 2, name: 'bar' },
]);
const updateState = () => {
setState((prevState) => [...prevState, { id: 3, name: 'baz' }]);
// [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }, { id: 3, name: 'baz' }]
};
もし、idが2のオブジェクトのnameを変更したいってときは、mapで返してあげれば出来ます。
setState((prevState) =>
prevState.map((obj) => (obj.id === 2 ? { id: obj.id, name: 'new' } : obj))
);
他にもReactHooksの記事を書いてます。
コメント