Bird
Raised Fist0
Reactframework~10 mins

Creating custom hooks in React - Visual Walkthrough

Choose your learning style10 modes available
Concept Flow - Creating custom hooks
Start Component
↓
Call Custom Hook
↓
Inside Hook: useState/useEffect
↓
Return State/Functions
↓
Component Uses Hook Data
↓
Render UI with Hook Data
↓
User Interaction -> State Update
↓
Re-render Component with New State
The component calls the custom hook, which manages state and effects, returns data and functions, and the component uses these to render and update UI.
Execution Sample
React
function useCounter() {
  const [count, setCount] = useState(0);
  const increment = () => setCount(c => c + 1);
  return { count, increment };
}

function Counter() {
  const { count, increment } = useCounter();
  return <button onClick={increment}>{count}</button>;
}
A custom hook useCounter manages a count state and increment function, used by Counter component to display and update count on button click.
Execution Table
StepActionState BeforeState AfterComponent Render Output
1Component Counter mounts, calls useCountercount: undefinedcount: 0<button>0</button>
2User clicks button, increment calledcount: 0count: 1<button>1</button>
3Component re-renders with updated countcount: 1count: 1<button>1</button>
4User clicks button again, increment calledcount: 1count: 2<button>2</button>
5Component re-renders with updated countcount: 2count: 2<button>2</button>
6No more clicks, component stablecount: 2count: 2<button>2</button>
💡 Execution stops when user stops interacting; state remains stable.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 4Final
countundefined0122
Key Moments - 3 Insights
Why does the component re-render after calling increment?
Because increment updates the state 'count' inside the custom hook, React triggers a re-render to update the UI, as shown in steps 2 and 3 of the execution_table.
Is the custom hook called multiple times or just once?
The custom hook is called on every render of the component, but React preserves the state between renders. This is why 'count' updates correctly as seen in the variable_tracker.
Can the custom hook return anything other than state and functions?
Yes, it can return any value needed by the component, but typically it returns state and functions to manage that state, as shown in the example where it returns { count, increment }.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'count' after Step 2?
A1
B0
C2
Dundefined
💡 Hint
Check the 'State After' column for Step 2 in the execution_table.
At which step does the component first render with count equal to 0?
AStep 1
BStep 3
CStep 4
DStep 5
💡 Hint
Look at the 'Component Render Output' column in the execution_table.
If the increment function did not update state, what would happen to the component render output?
AIt would update normally
BIt would never re-render with new count
CIt would crash
DIt would show an error message
💡 Hint
Refer to how state changes trigger re-renders in the execution_table and key_moments.
Concept Snapshot
Creating custom hooks:
- Define a function starting with 'use'
- Use React hooks inside (useState, useEffect)
- Return state and functions
- Call hook inside functional components
- State updates trigger re-renders
- Reuse logic cleanly across components
Full Transcript
This visual execution shows how a React component uses a custom hook to manage state. The custom hook useCounter initializes a count state to zero and provides an increment function. When the component mounts, it calls useCounter, which returns the current count and increment. The component renders a button showing the count. When the user clicks the button, increment updates the count state inside the hook. React detects this state change and re-renders the component with the new count value. The execution table traces each step: mounting, clicking, state updates, and re-renders. The variable tracker shows how the count changes from undefined to 0, then increments with each click. Key moments clarify why re-renders happen and how hooks preserve state across renders. The quiz tests understanding of state values at steps and the effect of state updates on rendering. The snapshot summarizes how to create and use custom hooks to share logic and state in React components.

Practice

(1/5)
1. What is the main reason to create a custom hook in React?
easy
A. To create new HTML elements
B. To reuse stateful logic across multiple components
C. To style components with CSS
D. To replace React components entirely

Solution

  1. Step 1: Understand the purpose of hooks

    Hooks let you use React features like state and effects inside functions.
  2. Step 2: Identify why custom hooks are used

    Custom hooks let you reuse stateful logic easily across components without repeating code.
  3. Final Answer:

    To reuse stateful logic across multiple components -> Option B
  4. Quick Check:

    Custom hooks = reuse logic [OK]
Hint: Custom hooks always reuse logic, not UI or styles [OK]
Common Mistakes:
  • Thinking custom hooks create UI elements
  • Confusing hooks with styling tools
  • Believing hooks replace components
2. Which of the following is the correct way to name a custom hook in React?
easy
A. hookUseFetch
B. fetchDataHook
C. FetchData
D. useFetchData

Solution

  1. Step 1: Recall naming rules for custom hooks

    Custom hooks must start with the word "use" to follow React conventions.
  2. Step 2: Check each option

    Only "useFetchData" starts with "use" correctly.
  3. Final Answer:

    useFetchData -> Option D
  4. Quick Check:

    Custom hook names start with "use" [OK]
Hint: Custom hooks always start with 'use' prefix [OK]
Common Mistakes:
  • Naming hooks without 'use' prefix
  • Using PascalCase without 'use'
  • Placing 'use' in the middle or end
3. Consider this custom hook code:
import { useState, useEffect } from 'react';

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  return width;
}

What will useWindowWidth() return when used inside a component?
medium
A. The height of the browser window
B. An error because window is undefined
C. The current width of the browser window, updating on resize
D. A function to resize the window

Solution

  1. Step 1: Analyze the hook's state and effect

    The hook uses state to store window.innerWidth and updates it on resize events.
  2. Step 2: Understand the returned value

    The hook returns the current width, which updates whenever the window resizes.
  3. Final Answer:

    The current width of the browser window, updating on resize -> Option C
  4. Quick Check:

    Custom hook returns updated window width [OK]
Hint: Custom hooks return values or functions, not errors here [OK]
Common Mistakes:
  • Confusing width with height
  • Thinking it returns a function
  • Assuming window is undefined in browser
4. What is wrong with this custom hook code?
import { useState, useEffect } from 'react';

function useCounter() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    setCount(count + 1);
  });
  return count;
}
medium
A. It causes an infinite loop because setCount is called inside useEffect without dependencies
B. It returns a function instead of a value
C. It will never update count because useEffect has an empty dependency array
D. It uses useState incorrectly by initializing with 0

Solution

  1. Step 1: Check useEffect dependencies

    The effect has no dependency array.
  2. Step 2: Understand setCount behavior

    setCount(count + 1) runs on every render since there are no dependencies, causing an infinite loop of re-renders.
  3. Final Answer:

    It causes an infinite loop because setCount is called inside useEffect without dependencies -> Option A
  4. Quick Check:

    Missing deps in useEffect = infinite loop [OK]
Hint: useEffect without deps array runs every render [OK]
Common Mistakes:
  • Thinking the effect runs only once without deps array
  • Confusing return value type
  • Misunderstanding dependency array role
5. You want to create a custom hook useFetch that fetches data from a URL and returns { data, loading, error }. Which approach correctly handles loading state and errors inside the hook?
hard
A. Use useState for data, loading, error; use useEffect to fetch and update states with try/catch inside async function
B. Use only useState for data and ignore loading and error states
C. Fetch data directly in the component and pass it to the hook as a parameter
D. Use useEffect without useState and return data from fetch promise

Solution

  1. Step 1: Identify state needs for fetch

    Fetching data requires tracking data, loading status, and errors, so useState is needed for all three.
  2. Step 2: Use useEffect with async fetch and error handling

    Inside useEffect, define an async function with try/catch to fetch data and update states accordingly.
  3. Final Answer:

    Use useState for data, loading, error; use useEffect to fetch and update states with try/catch inside async function -> Option A
  4. Quick Check:

    Fetch with useState and useEffect + try/catch [OK]
Hint: Manage data, loading, error with useState and useEffect [OK]
Common Mistakes:
  • Ignoring loading or error states
  • Fetching outside useEffect causing infinite loops
  • Returning unresolved promises
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard