What if you could write shared logic once and never copy it again?
Creating custom hooks in React - Why You Should Know This
Imagine you have several React components that need to share the same logic, like fetching data or handling a form input. You copy and paste the same code into each component.
Copying code everywhere makes your app hard to maintain. If you find a bug or want to improve the logic, you must update every copy. This wastes time and causes mistakes.
Creating custom hooks lets you write the shared logic once and reuse it easily in any component. This keeps your code clean, consistent, and easy to update.
import { useState, useEffect } from 'react'; function ComponentA() { const [count, setCount] = useState(0); useEffect(() => { console.log(count); }, [count]); // same logic repeated in ComponentB }
import { useEffect } from 'react'; function useCountLogger(count) { useEffect(() => { console.log(count); }, [count]); } function ComponentA() { const [count, setCount] = useState(0); useCountLogger(count); }
You can build cleaner, reusable logic blocks that work across many components, making your app easier to grow and fix.
Imagine a custom hook that handles user authentication status. Instead of repeating login checks in every page, you call the hook once and get consistent, up-to-date info everywhere.
Copy-pasting logic leads to bugs and wasted effort.
Custom hooks let you share logic cleanly across components.
This makes your React code easier to maintain and scale.
Practice
Solution
Step 1: Understand the purpose of hooks
Hooks let you use React features like state and effects inside functions.Step 2: Identify why custom hooks are used
Custom hooks let you reuse stateful logic easily across components without repeating code.Final Answer:
To reuse stateful logic across multiple components -> Option BQuick Check:
Custom hooks = reuse logic [OK]
- Thinking custom hooks create UI elements
- Confusing hooks with styling tools
- Believing hooks replace components
Solution
Step 1: Recall naming rules for custom hooks
Custom hooks must start with the word "use" to follow React conventions.Step 2: Check each option
Only "useFetchData" starts with "use" correctly.Final Answer:
useFetchData -> Option DQuick Check:
Custom hook names start with "use" [OK]
- Naming hooks without 'use' prefix
- Using PascalCase without 'use'
- Placing 'use' in the middle or end
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?Solution
Step 1: Analyze the hook's state and effect
The hook uses state to store window.innerWidth and updates it on resize events.Step 2: Understand the returned value
The hook returns the current width, which updates whenever the window resizes.Final Answer:
The current width of the browser window, updating on resize -> Option CQuick Check:
Custom hook returns updated window width [OK]
- Confusing width with height
- Thinking it returns a function
- Assuming window is undefined in browser
import { useState, useEffect } from 'react';
function useCounter() {
const [count, setCount] = useState(0);
useEffect(() => {
setCount(count + 1);
});
return count;
}Solution
Step 1: Check useEffect dependencies
The effect has no dependency array.Step 2: Understand setCount behavior
setCount(count + 1) runs on every render since there are no dependencies, causing an infinite loop of re-renders.Final Answer:
It causes an infinite loop because setCount is called inside useEffect without dependencies -> Option AQuick Check:
Missing deps in useEffect = infinite loop [OK]
- Thinking the effect runs only once without deps array
- Confusing return value type
- Misunderstanding dependency array role
useFetch that fetches data from a URL and returns { data, loading, error }. Which approach correctly handles loading state and errors inside the hook?Solution
Step 1: Identify state needs for fetch
Fetching data requires tracking data, loading status, and errors, so useState is needed for all three.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.Final Answer:
Use useState for data, loading, error; use useEffect to fetch and update states with try/catch inside async function -> Option AQuick Check:
Fetch with useState and useEffect + try/catch [OK]
- Ignoring loading or error states
- Fetching outside useEffect causing infinite loops
- Returning unresolved promises
Ready to prove it?
Pass the test and this pattern moves unknown
