Hooks let you share code between components easily. They keep your code clean and avoid repeating the same logic.
Reusing logic with hooks in React
Introduction
Syntax
React
function useCustomHook() { // use React hooks like useState, useEffect here return someValue; } function Component() { const value = useCustomHook(); return <div>{value}</div>; }
Custom hooks always start with use to follow React rules.
They can use other hooks inside and return any data or functions.
Examples
React
function useCounter() { const [count, setCount] = React.useState(0); const increment = () => setCount(c => c + 1); return { count, increment }; } function Counter() { const { count, increment } = useCounter(); return <button onClick={increment}>Count: {count}</button>; }
React
function useWindowWidth() { const [width, setWidth] = React.useState(window.innerWidth); React.useEffect(() => { const handleResize = () => setWidth(window.innerWidth); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); return width; } function ShowWidth() { const width = useWindowWidth(); return <div>Window width: {width}px</div>; }
Sample Program
This example shows a custom hook useToggle that manages on/off state. The ToggleButton component uses it to switch text and ARIA attributes for accessibility.
React
import React from 'react'; function useToggle(initialValue = false) { const [on, setOn] = React.useState(initialValue); const toggle = () => setOn(o => !o); return { on, toggle }; } export default function ToggleButton() { const { on, toggle } = useToggle(); return ( <button onClick={toggle} aria-pressed={on} aria-label="Toggle button"> {on ? 'ON' : 'OFF'} </button> ); }
Important Notes
Custom hooks help keep components small and focused on UI.
Always name hooks starting with use so React knows to follow hook rules.
Hooks can return any data type: values, objects, or functions.
Summary
Hooks let you reuse logic without repeating code.
Custom hooks start with use and can use other hooks inside.
Use them to keep your components clean and share behavior easily.
Practice
1. What is the main purpose of creating a custom hook in React?
easy
Solution
Step 1: Understand what hooks do
Hooks let you use React features like state and effects inside functions.Step 2: Identify the role of custom hooks
Custom hooks let you reuse this logic in many components without repeating code.Final Answer:
To reuse stateful logic across multiple components -> Option BQuick Check:
Custom hooks = reuse logic [OK]
Hint: Custom hooks start with 'use' and share logic [OK]
Common Mistakes:
- Thinking hooks create UI elements
- Confusing hooks with styling tools
- Believing hooks replace components
2. Which of the following is the correct way to define a custom hook in React?
easy
Solution
Step 1: Recall naming rules for custom hooks
Custom hooks must start with 'use' to follow React conventions and enable linting.Step 2: Check function names
Only function useCounter() { const [count, setCount] = useState(0); return [count, setCount]; } starts with 'use' and uses camelCase correctly.Final Answer:
function useCounter() { const [count, setCount] = useState(0); return [count, setCount]; } -> Option AQuick Check:
Custom hook names start with 'use' [OK]
Hint: Custom hooks always start with 'use' prefix [OK]
Common Mistakes:
- Not starting function name with 'use'
- Using uppercase first letter in hook name
- Naming hooks like regular functions
3. Given this custom hook code, what will be logged when
ExampleComponent renders?function useToggle(initial) {
const [on, setOn] = React.useState(initial);
const toggle = () => setOn(!on);
return [on, toggle];
}
function ExampleComponent() {
const [isOn, toggle] = useToggle(false);
React.useEffect(() => {
console.log(isOn);
}, [isOn]);
return Toggle;
}medium
Solution
Step 1: Analyze initial state in useToggle
The hook starts with initial = false, so isOn is false initially.Step 2: Understand useEffect logging
useEffect logs isOn after render; initially logs false, after toggle logs true.Final Answer:
false on first render, then true after button click -> Option DQuick Check:
Initial state false, toggles true [OK]
Hint: Initial state logs first, toggle changes it [OK]
Common Mistakes:
- Assuming initial state is true
- Thinking console.log won't run inside useEffect
- Confusing toggle function behavior
4. What is wrong with this custom hook code?
function useCounter() {
const [count, setCount] = React.useState(0);
function increment() {
count = count + 1;
}
return { count, increment };
}medium
Solution
Step 1: Check how state is updated
State variables like count must be updated via setCount, not by direct assignment.Step 2: Identify the error in increment
increment tries to assign count = count + 1, which does not update React state.Final Answer:
Directly modifying count variable instead of using setCount -> Option AQuick Check:
State updates need setCount [OK]
Hint: Always use setState to update state, never assign directly [OK]
Common Mistakes:
- Trying to assign state variable directly
- Forgetting to call setCount
- Confusing variable assignment with state update
5. You want to create a custom hook
useFetch that fetches data from a URL and returns loading state, data, and error. Which approach correctly reuses logic and handles updates safely?function useFetch(url) {
const [data, setData] = React.useState(null);
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState(null);
React.useEffect(() => {
setLoading(true);
fetch(url)
.then(res => res.json())
.then(json => {
setData(json);
setLoading(false);
})
.catch(err => {
setError(err.message);
setLoading(false);
});
}, [url]);
return { data, loading, error };
}hard
Solution
Step 1: Check useEffect dependency
useEffect runs when URL changes, so fetch updates correctly.Step 2: Verify state updates inside fetch
State updates happen after fetch resolves or errors, no infinite loops occur.Step 3: Confirm return value format
Returning an object with data, loading, error is a common pattern and valid.Final Answer:
This hook correctly reuses fetch logic and updates state on URL change -> Option CQuick Check:
useEffect fetches on URL change, updates state [OK]
Hint: useEffect with URL dependency safely fetches data [OK]
Common Mistakes:
- Thinking setState inside useEffect causes loops
- Not using useEffect for side effects
- Confusing return types of hooks
Recommended
Ready to prove it?
Pass the test and this pattern moves unknown
10 questions ~5 mineasy hard
