All quizzesHard
Hook Internals — Series 2
Preview — 3 of 10 questions
Why use useImperativeHandle here instead of simply doing useImperativeHandle(ref, () => videoRef.current) (exposing the raw DOM node directly)?
javascript
const VideoPlayer = forwardRef(function VideoPlayer(props, ref) {
const videoRef = useRef(null);
useImperativeHandle(ref, () => ({
play: () => videoRef.current.play(),
pause: () => videoRef.current.pause(),
}));
return <video ref={videoRef} src={props.src} />;
});
// Usage:
// const playerRef = useRef(null);
// <VideoPlayer ref={playerRef} src="..." />
// playerRef.current.play();AuseImperativeHandle lets the component author define a deliberately narrow, custom imperative API ({ play, pause }) instead of exposing the entire raw DOM element — the parent gets exactly the two methods the child intends to support, not arbitrary DOM access (videoRef.current.remove(), direct style mutation, etc.) that could bypass the component's own internal logic
BExposing the raw DOM node via a ref is not technically possible — useImperativeHandle is the only way to attach any ref value to a forwardRef component
CuseImperativeHandle is purely a TypeScript typing convenience with no runtime behavior difference from exposing the raw node
DUsing useImperativeHandle makes <video> render faster than a direct ref, since it avoids one layer of DOM lookup
What does useDebugValue(isOnline ? 'Online' : 'Offline') actually do at runtime, in a production build?
javascript
function useOnlineStatus() {
const [isOnline, setIsOnline] = useState(navigator.onLine);
useDebugValue(isOnline ? 'Online' : 'Offline');
useEffect(() => {
// ... subscribe to online/offline events
}, []);
return isOnline;
}AIt logs 'Online'/'Offline' to the console every time this custom hook is called, functioning as a lightweight built-in logger
BIt throws a runtime error in production builds — useDebugValue is a development-only API not meant to reach production code at all
CEssentially nothing observable to end users — useDebugValue exists purely to label a custom hook's value in React DevTools when inspecting components that use it; it has no effect on rendering, state, or behavior, and calling it is safe (just inert) in production
DIt attaches 'Online'/'Offline' as a data attribute on the nearest DOM element, visible via browser DevTools' Elements panel
Compared to writing const value = { user, setUser, theme, setTheme }; directly (a fresh object every render), what does wrapping it in useMemo actually fix?
javascript
function AppProvider({ children }) {
const [user, setUser] = useState(null);
const [theme, setTheme] = useState('dark');
const value = useMemo(
() => ({ user, setUser, theme, setTheme }),
[user, theme]
);
return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
}AIt prevents AppProvider itself from re-rendering when user or theme change
BIt ensures the value object passed to the Provider keeps the same reference across renders that don't actually change user or theme — since useContext consumers re-render whenever the Provider's value reference changes (not based on which specific field they read), this stops unrelated re-renders of AppProvider (e.g., ones triggered by something else entirely, or from a parent) from cascading into every context consumer, even though it does not fix the fan-out problem where changing just user still re-renders theme-only consumers too
CIt automatically splits AppContext into separate UserContext and ThemeContext under the hood, solving the fan-out re-render problem completely
DIt has no real effect here, since useState setters (setUser, setTheme) already keep the object reference stable on their own
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.