Skip to content

suhaotian/use-next-tick

Repository files navigation

A React hook for running callbacks after the DOM or native views have updated.

Why?

Sometimes you need to read the layout, measure elements, or access refs right after a state change—but React updates asynchronously. useNextTick provides a simple way to schedule code that runs after React commits your changes, without requiring an extra useEffect.

If you have used Vue.js before, you know nextTick; use-next-tick is the equivalent of nextTick for React.

Install

npm install use-next-tick

Usage

"use client";
import { useState, useRef, useLayoutEffect } from "react";
import useNextTick, { useNextTickLayout } from "use-next-tick";

function MyComponent() {
  const [count, setCount] = useState(0);
  const ref = useRef<HTMLSpanElement>(null);
  const nextTick = useNextTick();
  /*
  const nextTick = useNextTickLayout(); // if you need `useLayoutEffect` instead of `useEffect`
  */

  const handleClick = () => {
    setCount((c) => c + 1);
    nextTick(() => {
      console.log(ref.current?.textContent); // "1" ✓
    });
  };

  return <span ref={ref}>{count}</span>;
}

What it does

  1. You update state with setState
  2. You call nextTick(callback)
  3. React re-renders and commits to DOM/native
  4. Your callback runs with updated refs and layout

When to use it

Use useNextTick when:

  • Measuring elements after a state change
  • Reading layout values (width, height, position)
  • Focusing inputs after conditional rendering
  • One-off actions triggered by specific user events

Use useNextTickLayout when:

  • Scrolling to newly rendered content

Don't use it when:

  • You want something to happen on every render → use useEffect
  • You're just responding to prop/state changes → use useEffect with dependencies

Alternative without this hook

// Without useNextTick - requires separate useEffect
const [count, setCount] = useState(0);

const handleClick = () => {
  setCount((c) => c + 1);
};

useEffect(() => {
  // Runs after EVERY count change, not just from handleClick
  console.log(ref.current?.textContent);
}, [count]);

With useNextTick, you get imperative control—callbacks only run when you explicitly schedule them.

Online Demo

https://codesandbox.io/p/sandbox/react-dev-forked-jcljvj?file=%2Fsrc%2FApp.js%3A14%2C22

Platform support

Works on both React DOM (web) and React Native. Automatically uses the right scheduling mechanism for each platform.

Development

This project use bun.

bun install && bun run build

TypeScript

export default function useNextTick(
  useEffectHook?: typeof useEffect | typeof useLayoutEffect
): (cb: NextTickCallback) => void;

Fully typed. Callbacks can be sync or async:

nextTick(() => {
  console.log("sync callback");
});

nextTick(async () => {
  await someAsyncWork();
});

Reporting Issues

Found an issue? Please feel free to create issue

Support

If you find this project helpful, consider buying me a coffee.

Projects You May Also Be Interested In

  • xior - Tiny fetch library with plugins support and axios-like API
  • tsdk - Type-safe API development CLI tool for TypeScript projects
  • broad-infinite-list - ⚡ High performance and Bidirectional infinite scrolling list component for React and Vue3

About

A React hook for Running callbacks after the DOM or native views have updated.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors