Custom Hooks

Preview — 3 of 10 questions

When does useCallback actually prevent re-renders?

javascript
const Parent = () => {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    console.log("clicked");
  }, []); // memoized callback

  return (
    <>
      <button onClick={() => setCount(c => c + 1)}>+</button>
      <Child onClick={handleClick} />
    </>
  );
};

const Child = React.memo(({ onClick }) => {
  console.log("Child rendered");
  return <button onClick={onClick}>Action</button>;
});
AuseCallback prevents Child re-renders on its own
BuseCallback alone does nothing useful — it only helps when combined with React.memo: useCallback keeps the same function reference; React.memo skips re-render when props haven't changed
CReact.memo alone would prevent the re-render without useCallback
DuseCallback caches the result of the function, not the function itself

What does useMemo do?

javascript
function ProductList({ products, filter }) {
  const filtered = useMemo(
    () => products.filter(p => p.category === filter),
    [products, filter]
  );

  return filtered.map(p => <ProductCard key={p.id} product={p} />);
}
AuseMemo caches the component's render output
BuseMemo memoizes the computed value — filtered is recomputed only when products or filter changes, not on every render
CuseMemo is equivalent to useEffect but runs synchronously
DuseMemo prevents all re-renders of ProductList

When is useReducer preferable to useState?

javascript
const initialState = { count: 0, error: null, loading: false };

function reducer(state, action) {
  switch (action.type) {
    case "INCREMENT": return { ...state, count: state.count + 1 };
    case "SET_ERROR": return { ...state, error: action.payload, loading: false };
    case "FETCH_START": return { ...state, loading: true, error: null };
    default: return state;
  }
}

const [state, dispatch] = useReducer(reducer, initialState);
AuseReducer is always better than useState — always use it
BuseReducer is preferred when: state has multiple sub-values that change together, next state depends on previous, or update logic is complex; it centralizes transitions in one place
CuseReducer only works with objects, not primitives
DuseReducer re-renders more than useState

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.