Back to Machine Coding
Machine Coding
easy
mid

How would you build a dynamic N by M grid component in React?

A machine-coding task: render an N×M grid where N and M (and often cell state) are dynamic. Key points: derive the grid from state (a 1D or 2D array), drive columns with `grid-template-columns: repeat(N, 1fr)` from a variable, handle cell clicks immutably by index, keep keys stable, and lift configuration (size) to controlled inputs. Watch for re-render cost on large grids.

6 min read·~30 min to think through

"Build a dynamic grid" is an open machine-coding prompt — the interviewer watches your component structure, state modeling, and React fundamentals. Common variants: a grid whose size is configurable, cells that toggle on click, a "light box" puzzle, Conway's Game of Life.

Model the state first

Decide your data shape before writing JSX:

tsx
// Option A: 1D array, index = row * cols + col  (simple, fast)
const [cells, setCells] = useState<boolean[]>(() => Array(rows * cols).fill(false));

// Option B: 2D array  (intuitive, but harder to update immutably)
const [grid, setGrid] = useState<boolean[][]>(...);

1D is usually cleaner for updates. Keep rows/cols as their own state, driven by inputs.

Drive the layout from the variable

tsx
<div
  className="grid"
  style={{ gridTemplateColumns: `repeat(${cols}, 1fr)` }}
>
  {cells.map((on, i) => (
    <button
      key={i}
      className={on ? "cell cell--on" : "cell"}
      onClick={() => toggle(i)}
      aria-pressed={on}
    />
  ))}
</div>
css
.grid { display: grid; gap: 2px; }
.cell { aspect-ratio: 1; border: 1px solid #ccc; }

CSS Grid + grid-template-columns: repeat(N, 1fr) from state is the cleanest dynamic-grid mechanism.

Update immutably

tsx
function toggle(i: number) {
  setCells((prev) => {
    const next = [...prev];      // copy — never mutate prev
    next[i] = !next[i];
    return next;
  });
}

Use the functional updater so it's correct under batching, and copy before writing.

Controlled configuration

tsx
<input type="number" value={rows} onChange={(e) => setRows(+e.target.value)} />

Resizing should re-initialize the cells array (a useEffect on [rows, cols], or derive size into a key).

Things the interviewer is checking

  • State shape — did you pick something easy to update immutably?
  • Immutability — copy, don't mutate; functional updater.
  • Keys — stable (i is acceptable here since cells aren't reordered).
  • Layout — Grid driven by a variable, not hardcoded.
  • Accessibility — cells are <button>s, aria-pressed, keyboard-operable.
  • Performance — for large grids, each toggle re-renders the whole grid. Mention React.memo on the cell, or useReducer, and that for very large grids you'd virtualize or move to canvas.

Common follow-ups

  • "Now make cells toggle their neighbors" (lights-out puzzle).
  • "Add Game of Life rules" — a tick function over the array.
  • "10,000 cells — it's slow" — memoize cells, or canvas, or virtualize.

Senior framing

The senior approach is state-shape-first: choose a representation that makes the required updates trivial and immutable, derive the layout and rendering from it, and proactively name the re-render cost on large grids with concrete mitigations (memo, reducer, virtualization, canvas). Jumping straight to JSX without modeling state is the junior tell.

Follow-up questions

  • Why is a 1D array often easier than a 2D array for grid state?
  • How would you optimize a 100×100 grid where one cell toggles?
  • How would you implement 'clicking a cell toggles its neighbors'?

Common mistakes

  • Mutating the state array directly instead of copying.
  • Hardcoding the column count in CSS instead of driving it from state.
  • Not using the functional state updater.
  • Re-rendering all cells on every toggle with no memoization for large grids.

Edge cases

  • Resizing the grid must reconcile or reset the cell data.
  • Very large grids: DOM node count alone becomes the bottleneck → canvas.
  • Index keys are fine here only because cells never reorder.

Real-world examples

  • Game of Life, lights-out puzzles, pixel editors, seating charts, calendar grids.

Related questions