useArrayLoading saved progress…

useArray

Build a custom React hook that manages a list. Working with arrays in state is where a lot of React bugs are born: it is tempting to reach for push, splice, or sort, but those methods change the existing array in place — and React decides whether to re-render by checking whether the array is a new value, not by inspecting its contents. useArray(initial) owns the list and hands back the current array plus five helpers that change it the right way: set, push, remove, update, and clear.

Signature

function useArray<T>(initial?: T[]): {
  array: T[];
  set: (next: T[]) => void;
  push: (item: T) => void;
  remove: (index: number) => void;
  update: (index: number, item: T) => void;
  clear: () => void;
};

initial defaults to an empty array when omitted. set replaces the whole array; push appends one item; remove drops the element at an index; update replaces the element at an index; clear empties the list back to [].

Examples

function TagList() {
  const { array, push, remove, clear } = useArray(['react', 'hooks']);

  return (
    <div>
      {array.map((tag, i) => (
        <button key={i} onClick={() => remove(i)}>{tag} x</button>
      ))}
      <button onClick={() => push('state')}>add</button>
      <button onClick={clear}>clear</button>
    </div>
  );
}
// renders react, hooks; add -> react, hooks, state; clicking "hooks x" -> react, state
// Each helper returns a brand-new array; the old one is never mutated.
const { array, push, update, remove } = useArray([10, 20, 30]);
push(40);        // [10, 20, 30, 40]
update(0, 99);   // [99, 20, 30, 40]
remove(1);       // [99, 30, 40]

Notes

  • Never mutate the array in place. array.push(item) changes the existing array and keeps the same reference. React compares the new value to the old by reference, sees no change, and skips the re-render — so the screen goes stale.
  • Each helper makes a new array. Use non-mutating operations like spread ([...array, item]), filter, and map, which return fresh arrays and leave the original alone.
  • Helpers must survive batched updates. React groups several helper calls in one event into a single re-render, so updates have to stack correctly rather than each reading the same stale snapshot.
  • Out-of-range indices are harmless. remove(99) on a three-item list should leave the array unchanged, not throw.
  • You don't need to memoize the helpers for this version — returning fresh functions each render is acceptable. Stabilizing their identity is a separate exercise.
Loading editor…