Hooks

5 questions found

What are hooks in React and why were they introduced?

Beginner
Hooks are special functions, like useState and useEffect, that let a function component use features such as state and lifecycle behavior, which used to only be available in class components. They were introduced to make components simpler to write and to make it easier to reuse logic between components.
function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
Real-world example A team rewrites an old class based counter component into a much shorter function component using the useState hook, making the code easier to read and maintain.

Common follow-ups: What problems did hooks solve that class components struggled with?;Can hooks be used inside a class component?

Custom Hooks;Props & State

What does the useState hook do, and how do you use it?

Beginner
useState lets a function component remember a value between renders and gives you a function to update that value. Calling the update function tells React to re render the component with the new value.
function LikeButton() {
  const [liked, setLiked] = useState(false);
  return (
    <button onClick={() => setLiked(!liked)}>
      {liked ? 'Liked' : 'Like'}
    </button>
  );
}
Real-world example A social media post's like button remembers whether the current user has already liked it, using useState to toggle between a liked and unliked appearance whenever the button is clicked.

Common follow-ups: Why does calling the state setter not immediately change the value inside the current render?;Can you store an object or an array inside useState?

Props & State;Effects & Lifecycle

What is the useReducer hook and when is it a better choice than useState?

Intermediate
useReducer manages state using a function called a reducer, which decides how the state should change based on an action you send it. It becomes a better choice than useState when a component has several related pieces of state that often change together, or when the logic for updating state grows complicated.
function reducer(state, action) {
  switch (action.type) {
    case 'increment': return { count: state.count + 1 };
    case 'reset': return { count: 0 };
    default: return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });
  return <button onClick={() => dispatch({ type: 'increment' })}>{state.count}</button>;
}
Real-world example A shopping cart with many related pieces of state, like items, quantity, and discounts, switches from several separate useState calls to a single useReducer, making all the related update logic live in one clear place.

Common follow-ups: How do you decide between using useState and useReducer for a specific component?;Can useReducer be combined with the Context API to share state widely?

useReducer & Complex State Logic;State Management

What is the useMemo hook and how does it help with performance?

Intermediate
useMemo remembers the result of an expensive calculation and only recalculates it when one of its listed dependencies actually changes. This avoids repeating slow work on every single render if the inputs to that calculation have not changed.
function ProductList({ products, searchTerm }) {
  const filteredProducts = useMemo(
    () => products.filter((p) => p.name.includes(searchTerm)),
    [products, searchTerm]
  );
  return <ul>{filteredProducts.map((p) => <li key={p.id}>{p.name}</li>)}</ul>;
}
Real-world example A product list with thousands of items avoids re filtering the entire list on every unrelated re render, since useMemo only recalculates the filtered results when the actual product list or search term changes.

Common follow-ups: Should useMemo be used for every calculation in a component, even simple ones?;What is the difference between useMemo and useCallback?

Performance (memo/useMemo);Effects & Lifecycle

What are the rules of hooks, and why do they exist?

Advanced
Hooks must always be called in the exact same order on every render, so they should only be called at the top level of a component or a custom hook, never inside loops, conditions, or nested functions. This rule exists because React relies on that consistent order to correctly match each hook call to its own stored state between renders.
// Breaks the rule, hook is called conditionally
if (showDetails) {
  const [details, setDetails] = useState(null);
}

// Follows the rule, hook always called, condition handled inside
const [details, setDetails] = useState(null);
if (showDetails) {
  // use details here
}
Real-world example A developer fixes a strange bug where a component's state seemed to get mixed up between different fields, after discovering a useState call was hidden inside a conditional statement, breaking the required consistent hook order.

Common follow-ups: What specific error message does React show when this rule is broken?;How does the official eslint plugin for hooks help catch these mistakes automatically?

Custom Hooks;React DevTools & Debugging