Because React uses Object.is
to compare equality we need to ensure that the new object we pass to setState
has a different reference.
I'd do this with a little custom hook. It could look something like so:
function useStateArray<T>(initialVal: T[]) {
const [arr, setArr] = useState(initialVal);
const push = React.useCallback(
(val: T) => setArr((old) => [...old, val]),
[]
);
const edit = React.useCallback((val: Partial<T>, index: number) => {
setArr((old) => {
const newArr = [...old];
newArr[index] = { ...newArr[index], ...val };
// We need to return a new array to update the state!
return newArr;
});
}, []);
return [arr, push, edit, setArr];
}
The idea being that if you're using arrays in your useState
a lot it might make sense to have a few helper functions ready to go.
You could then add some other utility functions (like delete, pop, etc).