A React hook for running callbacks after the DOM or native views have updated.
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.
npm install use-next-tick"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>;
}- You update state with
setState - You call
nextTick(callback) - React re-renders and commits to DOM/native
- Your callback runs with updated refs and layout
✅ 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
useEffectwith dependencies
// 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.
Works on both React DOM (web) and React Native. Automatically uses the right scheduling mechanism for each platform.
This project use bun.
bun install && bun run buildexport 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();
});Found an issue? Please feel free to create issue
If you find this project helpful, consider buying me a coffee.
- 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