What if you could fix a bug once and watch it update everywhere instantly?
Why Reusing logic with hooks in React? - Purpose & Use Cases
Imagine you have several React components that need to share the same behavior, like fetching data or handling a timer. 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.
Hooks let you write the shared logic once and reuse it in many components. This keeps your code clean, easy to update, and consistent across your app.
function ComponentA() {
useEffect(() => {
// fetch data logic here
}, []);
// repeated in ComponentB
}import { useEffect } from 'react'; function useFetchData() { useEffect(() => { // fetch data logic here }, []); } function ComponentA() { useFetchData(); } function ComponentB() { useFetchData(); }
You can build cleaner, more reliable React apps by sharing logic easily and avoiding repeated code.
Think of a timer hook that counts seconds. Instead of writing timer code in every component, you write one hook and use it wherever you need a timer.
Copy-pasting logic causes bugs and wastes time.
Hooks let you share logic cleanly across components.
This makes your app easier to maintain and improve.
Practice
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]
- Thinking 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 '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]
- Not starting function name with 'use'
- Using uppercase first letter in hook name
- Naming hooks like regular functions
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;
}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]
- Assuming initial state is true
- Thinking console.log won't run inside useEffect
- Confusing toggle function behavior
function useCounter() {
const [count, setCount] = React.useState(0);
function increment() {
count = count + 1;
}
return { count, increment };
}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]
- Trying to assign state variable directly
- Forgetting to call setCount
- Confusing variable assignment with state update
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 };
}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]
- Thinking setState inside useEffect causes loops
- Not using useEffect for side effects
- Confusing return types of hooks
Ready to prove it?
Pass the test and this pattern moves unknown
