HardRefs & Side Effects💻 Output Question

useImperativeHandle — expose limited API via ref

💡

Hint

useImperativeHandle prevents parents from directly accessing internal DOM nodes or state. Expose only the API you want to maintain — it's the ref equivalent of keeping implementation details private.

What does this output?

// Simulates useImperativeHandle
function createImperativeHandle(ref, factory) {
  ref.current = factory();
}

// Child exposes ONLY what it wants
function VideoPlayer(ref) {
  const internal = {
    play()  { return 'playing'; },
    pause() { return 'paused'; },
    seek(t) { return 'seeked to ' + t; },
    _internalState: 'hidden', // should NOT be exposed
  };

  createImperativeHandle(ref, () => ({
    play:  () => internal.play(),
    pause: () => internal.pause(),
    // seek and _internalState NOT exposed
  }));
}

const playerRef = { current: null };
VideoPlayer(playerRef);

console.log(typeof playerRef.current.play);
console.log(typeof playerRef.current.seek);
console.log(playerRef.current._internalState);
console.log(playerRef.current.play());

Correct Output

function
undefined
undefined
playing

Why this output?

Explanation: useImperativeHandle replaces ref.current with a custom object. Only play and pause are exposed. seek and _internalState are hidden.

Key Insight: useImperativeHandle prevents parents from directly accessing internal DOM nodes or state. Expose only the API you want to maintain — it's the ref equivalent of keeping implementation details private.

Practice predicting output live →

66 output questions with instant feedback

💻 Try Output Quiz