Home
React
Advanced Hook: Custom Hooks
Daniel Nguyen
Daniel Nguyen
July 12, 2025
1 min

1. What Is a Custom Hook?

A custom Hook is a JavaScript function that uses React Hooks to reuse stateful logic across components.

Its name must start with use, and it must follow the Rules of Hooks.

function useCount() {
const [count, setCount] = useState(0)
const increment = () => {
setCount(c => c + 1)
}
return { count, increment }
}

Use it like any other Hook:

function Counter() {
const { count, increment } = useCount()
return <button onClick={increment}>{count}</button>
}

Each call to useCount() has its own state. Custom Hooks share logic, not state, unless they connect to a shared store or Context.

2. The Problem: Function References Change

Consider this effect:

useEffect(() => {
const id = setInterval(increment, 1000)
return () => clearInterval(id)
}, [increment])

If increment is declared directly inside a custom Hook, a new function is created on each render.

Because its reference changes, React cleans up the previous effect and runs it again after each render.

For an interval, that means repeatedly resetting the timer.

3. Fix with useCallback

function useCount() {
const [count, setCount] = useState(0)
const increment = useCallback(() => {
setCount(c => c + 1)
}, [])
return { count, increment }
}

The functional state update setCount(c => c + 1) means the callback does not need to capture count, so the empty dependency array is correct.

Now increment retains the same reference between renders, allowing effects that depend on it to avoid unnecessary resynchronization.

Important: useCallback is useful when function identity matters. It is not necessary for every event handler.

4. Memoization

Memoization reuses a previously calculated result while its dependencies remain unchanged.

React provides two related Hooks:

  • useMemo caches a calculated value.
  • useCallback caches a function reference.
const total = useMemo(() => calculateTotal(items), [items])
const handleClick = useCallback(() => {
submitForm(formData)
}, [formData])

These Hooks can help avoid expensive calculations or unnecessary re-renders when passed to memoized child components.


Tags

#ReactAdvancedHooks

Share

Daniel Nguyen

Daniel Nguyen

Frontend Developer

Frontend developer specializing in React, Next.js, and JavaScript. Writing practical guides on modern web development at Dev98.

Expertise

React
Next.js
JavaScript
TypeScript
Python

Social Media

githublinkedinyoutubewebsite

Related Posts

Advanced Hook
Advanced Hook: useSyncExternalStore()
July 19, 2025
1 min
Dev98

Dev98

React · Next.js · Web development