Consider the following React custom hook and component. What will be displayed when the component renders?
import React, { useState, useEffect } from 'react'; function useCounter(initial) { const [count, setCount] = useState(initial); useEffect(() => { const id = setInterval(() => setCount(c => c + 1), 1000); return () => clearInterval(id); }, []); return count; } function Counter() { const count = useCounter(0); return <div>{count}</div>; }
Think about how useEffect with an empty dependency array works and how setInterval updates state.
The custom hook useCounter initializes state to the given initial value (0). The useEffect sets up an interval that increments the count every second. The component renders the current count, so it starts at 0 and increments by 1 every second.
Which of the following custom hooks correctly returns the current window width and updates on resize?
Remember to clean up event listeners in useEffect to avoid memory leaks.
Option C correctly sets up a resize event listener inside useEffect and cleans it up on unmount. Option C adds listeners on every render causing leaks. Option C assigns window.onresize but does not clean up. Option C adds listener but never removes it.
Examine the custom hook below. Why does it cause an infinite render loop?
import { useState, useEffect } from 'react'; function useData() { const [data, setData] = useState(null); useEffect(() => { fetch('https://api.example.com/data') .then(res => res.json()) .then(json => setData(json)); }, [data]); return data; }
Think about what triggers useEffect and how state updates affect dependencies.
The effect depends on 'data', so every time 'data' changes, the effect runs again, fetching data and updating state, which triggers the effect again. This creates an infinite loop. The dependency array should be empty or include only stable dependencies.
Given this custom hook and component, what will be the value of count after clicking the button twice quickly?
import React, { useState } from 'react'; function useCounter() { const [count, setCount] = useState(0); const increment = () => { setCount(count + 1); setCount(count + 1); }; return [count, increment]; } function Counter() { const [count, increment] = useCounter(); return <button onClick={increment}>{count}</button>; }
Remember that React state updates may be batched and that setCount(count + 1) uses the current closure value.
The increment function closes over the count value from the render when it was created. Within one click, both setCount(count + 1) calls use the same stale count and batch to a single update (+1). For two quick clicks before re-render, the second click uses the same increment function (still closing over the initial count), queuing more sets to the same value. Thus, count shows 1.
Why is it important that custom React hooks start with the prefix use?
Think about how React detects hooks and enforces rules like calling hooks only at the top level.
React uses the 'use' prefix to detect hook calls and apply the rules of hooks. This detection helps React warn about incorrect usage and ensures hooks work correctly. Without the prefix, React cannot identify the function as a hook.