Back to Machine Coding
Machine Coding
easy
mid

How would you build a grid light box in React where lights deactivate in the reverse order of activation?

Track an ordered array of activated cell ids in state. On click, if not active, push; if already active, ignore (or toggle off). Once all activated, deactivate one-by-one (setInterval) in reverse order via .pop(). Render: each cell highlights if its id is in the array. Clean up the interval on unmount and when the array empties.

3 min read·~20 min to think through

Classic React coding question — tests state, ordering, and timing.

Spec recap

  • 3x3 grid (or NxN).
  • Click an unlit cell → it lights up.
  • Track activation order.
  • Once all N cells are lit, deactivate them one-by-one (e.g. every 300ms) in reverse activation order.
  • Clicking a lit cell during activation phase: typically ignored.

Implementation

tsx
import { useState, useEffect } from 'react';

const N = 9;

export function LightGrid() {
  const [active, setActive] = useState<number[]>([]);
  const [deactivating, setDeactivating] = useState(false);

  function onClick(i: number) {
    if (deactivating) return;
    if (active.includes(i)) return;
    setActive((prev) => [...prev, i]);
  }

  useEffect(() => {
    if (active.length !== N) return;
    setDeactivating(true);
    const id = setInterval(() => {
      setActive((prev) => {
        const next = prev.slice(0, -1);          // pop last
        if (next.length === 0) {
          clearInterval(id);
          setDeactivating(false);
        }
        return next;
      });
    }, 300);
    return () => clearInterval(id);
  }, [active.length]);

  return (
    <div className="grid grid-cols-3 gap-2">
      {Array.from({ length: N }, (_, i) => (
        <button
          key={i}
          onClick={() => onClick(i)}
          disabled={deactivating}
          className={
            'h-16 w-16 rounded border ' +
            (active.includes(i) ? 'bg-green-500' : 'bg-gray-200')
          }
        />
      ))}
    </div>
  );
}

Walk-through

  • active is the ordered list of activated cell indices.
  • onClick: add if not present and not deactivating.
  • When active.length === N, kick off deactivation interval.
  • Each tick pops from the end (reverse activation order).
  • Clean up interval on unmount and when the array empties.

Edge cases / interview probes

  • Double-click: ignored (includes guard).
  • Unmount mid-deactivation: cleanup clears interval.
  • Variable grid size: parametrize N.
  • Animate the light fade: add CSS transition on the bg color; transition-colors duration-200.
  • Pause on hover: clear interval on onMouseEnter, restart on leave (extra credit).
  • What if user clicks before all 9 fill? Just adds to active.

Variations interviewers ask

  • Reverse with delay reuse (use the time intervals between activations).
  • Re-activatable after full cycle.
  • N×M grid with different N.
  • Animation per cell with transition end events.

Anti-patterns

  • Tracking active as a Set — loses order.
  • Setting state inside the effect's cleanup function.
  • Using a single useState for both array and flag (couples them).

Interview framing

"Array of activated cell ids in state — keeps order. onClick guards against double-add and against clicking during deactivation. Effect watches active.length; when it reaches N, kick off a setInterval that pops the last element each tick (reverse order). Cleanup clears the interval on unmount and when the array empties. Add a deactivating flag to disable clicks during the deactivation phase. The key is using an array (preserves order) not a Set, and putting deactivation in an effect so cleanup is automatic."

Follow-up questions

  • What if the user could click during deactivation?
  • How would you pause on hover?
  • How would you animate the light fading out?

Common mistakes

  • Using Set (loses order).
  • Missing cleanup on interval.
  • Allowing clicks during deactivation.

Performance considerations

  • Trivial. State + interval; one re-render per tick.

Edge cases

  • Unmount mid-deactivation.
  • Rapid clicks before fill.
  • Variable N.

Real-world examples

  • Frontend coding round at many companies (Atlassian, Razorpay, etc.).

Senior engineer discussion

Seniors handle edge cases (cleanup, race, mid-cycle clicks) and propose extensions (animations, pause, replay).

Related questions