Frontend Development 8 min read

Understanding useCallback and Building a Custom Countdown Hook in React

This article explores the purpose and proper usage of React's useCallback hook, examines common pitfalls, and demonstrates how to build and enhance a reusable countdown custom hook, including handling callbacks, effect dependencies, and ref-based solutions for stable function references.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Understanding useCallback and Building a Custom Countdown Hook in React

Introduction: The author reflects on recent insights about useCallback and a friend's interview question about implementing a countdown hook, prompting a deeper understanding of React hooks.

Discussion on why many open‑source hooks store parameters in ref objects and access them via .current , noting the extra complexity compared to using plain variables.

Explanation of when to use useCallback :

Stage 1 – discovering that useCallback can cache a function to prevent it from being recreated on every render, which helps avoid infinite loops in useEffect dependency arrays.

Stage 2 – assuming that caching always improves performance, leading to over‑use of useCallback together with memo for child components.

Stage 3 – realizing that unnecessary caching can be counter‑productive because the overhead may outweigh the benefits.

Key takeaways from each stage are highlighted, emphasizing that useCallback should be applied judiciously.

Summary of proper scenarios for useCallback :

When a parent component passes a function prop to a memoized child component, the function should be wrapped with useCallback to keep the prop stable.

When a function appears in a useEffect dependency array, wrapping it with useCallback prevents the effect from running endlessly.

When a custom hook returns a function that may be used as a useEffect dependency, the returned function should be memoized with useCallback .

Implementation of a custom useCountdown hook is presented:

The hook accepts a duration and returns the current count and a start function.

Initial version creates a timer in a button component; the logic is extracted into the hook.

Later the hook is upgraded to accept optional callbacks for each tick and for completion, using a configuration object with countdownCallBack and onEnd .

To avoid stale references for external callbacks, the solution employs useRef (or utilities like useLatest / useMemoizedFn from the ahooks library) to store the latest versions without adding them to the useEffect dependency array.

Final conclusions reiterate two core points: a refreshed understanding of useCallback (and its sibling useMemo ) usage scenarios, and best practices for writing custom hooks that safely handle external inputs and provide reliable outputs.

frontendJavaScriptreactuseCallbackCustom Hook
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.