You can use useEffect/useLayoutEffect to achieve this:

const SomeComponent = () => {
  const [count, setCount] = React.useState(0)

  React.useEffect(() => {
    if (count > 1) {
      document.title = 'Threshold of over 1 reached.';
    } else {
      document.title = 'No threshold reached.';
    }
  }, [count]);

  return (
    <div>
      <p>{count}</p>

      <button type="button" onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </div>
  );
};

If you want to prevent the callback from running on first render, adjust the previous version:

const SomeComponent = () => {
  const [count, setCount] = React.useState(0)

  const didMount = React.useRef(false);

  React.useEffect(() => {
    if (!didMount.current) {
      didMount.current = true;
      return;
    }

    if (count > 1) {
      document.title = 'Threshold of over 1 reached.';
    } else {
      document.title = 'No threshold reached.';
    }
  }, [count]);

  return (
    <div>
      <p>{count}</p>

      <button type="button" onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </div>
  );
};

More about it over here.

Answer from Robin Wieruch on Stack Overflow
🌐
React
react.dev › reference › react › useState
useState – React
Call useState at the top level of your component to declare one or more state variables.
Top answer
1 of 8
179

You can use useEffect/useLayoutEffect to achieve this:

const SomeComponent = () => {
  const [count, setCount] = React.useState(0)

  React.useEffect(() => {
    if (count > 1) {
      document.title = 'Threshold of over 1 reached.';
    } else {
      document.title = 'No threshold reached.';
    }
  }, [count]);

  return (
    <div>
      <p>{count}</p>

      <button type="button" onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </div>
  );
};

If you want to prevent the callback from running on first render, adjust the previous version:

const SomeComponent = () => {
  const [count, setCount] = React.useState(0)

  const didMount = React.useRef(false);

  React.useEffect(() => {
    if (!didMount.current) {
      didMount.current = true;
      return;
    }

    if (count > 1) {
      document.title = 'Threshold of over 1 reached.';
    } else {
      document.title = 'No threshold reached.';
    }
  }, [count]);

  return (
    <div>
      <p>{count}</p>

      <button type="button" onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </div>
  );
};

More about it over here.

2 of 8
157

setState(updater, callback) for useState

Following implementation comes really close to the original setState callback of classes.

Improvements made to accepted answer:

  1. Callback execution is omitted on initial render - we only want to call it on state updates
  2. Callback can be dynamic for each setState invocation, like with classes

Usage

const App = () => {
  const [state, setState] = useStateCallback(0); // same API as useState

  const handleClick = () => {
    setState(
      prev => prev + 1,
      // second argument is callback, `s` being the *updated* state
      s => console.log("I am called after setState, state:", s)
    );
  };

  return <button onClick={handleClick}>Increment</button>;
}

useStateCallback

function useStateCallback(initialState) {
  const [state, setState] = useState(initialState);
  const cbRef = useRef(null); // init mutable ref container for callbacks

  const setStateCallback = useCallback((state, cb) => {
    cbRef.current = cb; // store current, passed callback in ref
    setState(state);
  }, []); // keep object reference stable, exactly like `useState`

  useEffect(() => {
    // cb.current is `null` on initial render, 
    // so we only invoke callback on state *updates*
    if (cbRef.current) {
      cbRef.current(state);
      cbRef.current = null; // reset callback after execution
    }
  }, [state]);

  return [state, setStateCallback];
}
TypeScript version
function useStateCallback<T>(
  initialState: T
): [T, (state: T, cb?: (state: T) => void) => void] {
  const [state, setState] = useState(initialState);
  const cbRef = useRef<((state: T) => void) | undefined>(undefined); // init mutable ref container for callbacks

  const setStateCallback = useCallback((state: T, cb?: (state: T) => void) => {
    cbRef.current = cb; // store current, passed callback in ref
    setState(state);
  }, []); // keep object reference stable, exactly like `useState`

  useEffect(() => {
    // cb.current is `undefined` on initial render,
    // so we only invoke callback on state *updates*
    if (cbRef.current) {
      cbRef.current(state);
      cbRef.current = undefined; // reset callback after execution
    }
  }, [state]);

  return [state, setStateCallback];
}

Further info: React Hooks FAQ: Is there something like instance variables?

Working example

const App = () => {
  const [state, setState] = useStateCallback(0);

  const handleClick = () =>
    setState(
      prev => prev + 1,
      // important: use `s`, not the stale/old closure value `state`
      s => console.log("I am called after setState, state:", s)
    );

  return (
    <div>
      <p>Hello Comp. State: {state} </p>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
}

function useStateCallback(initialState) {
  const [state, setState] = useState(initialState);
  const cbRef = useRef(null);

  const setStateCallback = useCallback((state, cb) => {
    cbRef.current = cb; 
    setState(state);
  }, []);

  useEffect(() => {
    if (cbRef.current) {
      cbRef.current(state);
      cbRef.current = null;
    }
  }, [state]);

  return [state, setStateCallback];
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js" integrity="sha256-32Gmw5rBDXyMjg/73FgpukoTZdMrxuYW7tj8adbN8z4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js" integrity="sha256-bjQ42ac3EN0GqK40pC9gGi/YixvKyZ24qMP/9HiGW7w=" crossorigin="anonymous"></script>
<script>var { useReducer, useEffect, useState, useRef, useCallback } = React</script>
<div id="root"></div>

Discussions

Callbacks in useState? No? This is stupid, PLEASE change my view.
I'm really frustrated right now. I'm begrudgingly making the transition to functional components instead of class components, and I'm doing so… More on reddit.com
🌐 r/reactjs
31
0
June 12, 2022
When does the callback inside the setter function of the useState hook execute?
The React documentation describes the setter function of the useState hook as follows: React waits until all code in the event handlers has run before processing your state updates. React queues this function(callback inside the setter) ... More on github.com
🌐 github.com
4
April 30, 2023
useState: when to use callback
I am working on the course over useState and useEffect. I get the general premise of the topic at hand. But I caught myself wondering why the callback function is used in some occasions and not others within the state setter funcitons. setCount(prevCount => prevCount + 1) When our state setter ... More on discuss.codecademy.com
🌐 discuss.codecademy.com
0
0
August 14, 2023
How does Javascript/React know to pass in the previous value of a stateful variable?
React keeps the actual current props and state for each component in internal data structures called "Fibers". That's how it knows what components currently exist in the component tree, and how to update them. In this case, when you pass an updater function into setState, React will eventually call const newState = updaterFunction(fiber.prevState). See my extensive post A (Mostly) Complete Guide to React Rendering Behavior to better understand how this actually works. More on reddit.com
🌐 r/reactjs
15
0
June 9, 2024
🌐
Robin Wieruch
robinwieruch.de › react-usestate-callback
React useState with Callback
For instance, if you want to have ... this state: ... The function you pass to the useEffect hook is your callback function which runs after the provided state changes from the useState hook's second argument....
🌐
Medium
medium.com › @atshn.gunduz › usestate-callback-29278203e498
useState() callback - by Ateshan Gunduz
December 1, 2023 - useState() callback In React useState() empower us to update the state by passing a new value or by a function that returns a new value. Using this function as part of the useState() hook, is …
🌐
React
react.dev › reference › react › useCallback
useCallback – React
Sometimes, you might need to update state based on previous state from a memoized callback. This handleAddTodo function specifies todos as a dependency because it computes the next todos from it: function TodoList() { const [todos, setTodos] = useState([]); const handleAddTodo = useCallback((text) => { const newTodo = { id: nextId++, text }; setTodos([...todos, newTodo]); }, [todos]); // ...
🌐
Medium
maksimrv.medium.com › usestate-with-callback-d574298eb8bd
React: useState hook with callback | by Maksim Ryzhikov | Medium
November 15, 2020 - But with new “functional” oriented React where you described components using plain functions you should use `useState` hook to track internal component’s state inside function. const [state, setState] = useState(null);setState(newState, myCallback) The `setState` above would throw warning and don’t call `myCallback` because `useState` does not support callbacks and say that you should use `useEffect` for this purpose.
🌐
Reddit
reddit.com › r/reactjs › callbacks in usestate? no? this is stupid, please change my view.
r/reactjs on Reddit: Callbacks in useState? No? This is stupid, PLEASE change my view.
June 12, 2022 - That's the beauty of hooks. Whatever logic you define using useState, useEffect, yes even that mount detect etc., can be extracted into yet another hook. VSCode: right click, refactor to module scope.
Find elsewhere
🌐
React
legacy.reactjs.org › docs › hooks-reference.html
Hooks API Reference – React
useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. useReducer also lets you optimize performance for components that trigger deep updates because you can pass dispatch down instead of callbacks.
🌐
GitHub
github.com › the-road-to-learn-react › use-state-with-callback
GitHub - the-road-to-learn-react/use-state-with-callback: Custom hook to include a callback function for useState. · GitHub
Next.js) // import { useStateWithCallbackInstant } from 'use-state-with-callback'; const App = () => { const [count, setCount] = useStateWithCallback(0, currentCount => { console.log('render, then callback.'); console.log('otherwise use useStateWithCallbackInstant()'); if (currentCount > 1) { console.log('Threshold of over 1 reached.'); } else { console.log('No threshold reached.'); } }); // const [count, setCount] = useStateWithCallbackInstant(0, currentCount => { // console.log('render with instant callback.'); // if (currentCount > 1) { // console.log('Threshold of over 1 reached.'); // } e
Starred by 278 users
Forked by 37 users
Languages   JavaScript
🌐
GitHub
github.com › reactjs › react.dev › issues › 5982
When does the callback inside the setter function of the useState hook execute? · Issue #5982 · reactjs/react.dev
April 30, 2023 - The React documentation describes the setter function of the useState hook as follows: React waits until all code in the event handlers has run before processing your state updates. React queues this function(callback inside the setter) ...
Author   nelvko
🌐
Codedamn
codedamn.com › news › react js
React useState callback tutorial
September 19, 2022 - In this section, you’re going to learn about how to use a callback with the useState hook. As part of the class component, we could pass a second argument to the setState function. However, the setState function returned by theuseState hook in the functional component does not take an extra argument. In the old “class” oriented React version you could call setState and pass it as a second argument function which would be called when the state of the component would be updated.
🌐
npm
npmjs.com › package › use-state-with-callback
use-state-with-callback - npm
April 14, 2022 - Custom hook to include a callback function for useState which was previously available for setState in class components. Read more about it here. ... import * as React from 'react'; import useStateWithCallback from 'use-state-with-callback'; // Note: cannot be used on the server-side (e.g.
      » npm install use-state-with-callback
    
🌐
DEV Community
dev.to › yoonthecoder › understanding-reacts-usestate-with-callback-functions-a-deep-dive-39g7
Understanding React's useState with Callback Functions: A Deep Dive - DEV Community
January 15, 2025 - Using callback functions with useState is essential for reliable state updates in React. They help prevent race conditions, ensure state updates are based on the most recent values, and make your code more predictable.
🌐
DEV Community
dev.to › mubbashir10 › callback-solution-for-usestate-hook-in-react-1ni0
Callback solution for useState hook in React - DEV Community
January 2, 2025 - import React, { Component } from 'react'; class App extends Component { constructor(props) { super(props); this.state = { beer: 0, }; } updateBeerCount = value => { this.setState({ beer: value}, ()=>{ console.log('count updated!, I\'m the callback'); }); }; render() { return ( <div> <p>Try increasing the number and check your console!</p> <input type="number" value={this.state.beer} onChange={e => this.updateBeerCount(e.target.value)} /> </div> ); } } export default App;
🌐
Plain English
plainenglish.io › blog › how-to-use-callback-in-usestate-hook-afe4113d9ac0
How to Use Callback in the useState() Hook?
August 24, 2021 - const [state, setState] = useState(); useEffect(() => {callbackFunction()}, [state])
🌐
W3Schools
w3schools.com › react › react_usecallback.asp
React useCallback Hook
The memoized callback will only change if one of these dependencies has changed. ... //Without useCallback: import React, { useState } from 'react'; import { createRoot } from 'react-dom/client'; // Child component that receives a function prop const Button = React.memo(({ onClick, text }) => { alert(`Child ${text} button rendered`); return <button onClick={onClick}>{text}</button>; }); // Parent component without useCallback function WithoutCallbackExample() { const [count1, setCount1] = useState(0); const [count2, setCount2] = useState(0); // This function is recreated on every render const
🌐
Carlogino
carlogino.com › blog › react-usestate-callback-function
React useState callback function
12345678910function UseStateDemo() { const complexFunction = () => { // Something computationally expensive return 'result of a heavy task' } const [,setState] = React.useState(complexFunction()) return <button onClick={() => setState(Date.now())} >Click Me</button>}
🌐
Dushkin
dushkin.tech › posts › stale_state_react
How to fix stale React useState's state in a callback | Dmitrii Dushkin blog
June 7, 2025 - export default function App() { const [isOpen, setIsOpen] = useState(false); const [state, setState] = useState(""); console.log("State's value on render =", state); // This function is created each time on every re-render // So it holds a correct state value const callbackFn = () => { console.log("State value inside callbackFn =", state); setIsOpen(false); }; const modalOptions = { onCloseStart: callbackFn, }; return ( <div className="App"> <Button onClick={() => setIsOpen(true)}>Show modal</Button> {/** Modal component from react-materialize We defined a callback which will be fired on modal close.
🌐
Codecademy Forums
discuss.codecademy.com › web development › full-stack
useState: when to use callback - Full-Stack - Codecademy Forums
August 14, 2023 - But I caught myself wondering why ... setCount(prevCount => prevCount + 1) When our state setter calls the callback function, this state setter callback function takes our previous count as an argument....
🌐
LinkedIn
linkedin.com › pulse › provide-callback-usestate-hook-like-setstate-saransh-kataria
Provide callback to useState hook like setState
December 17, 2020 - We will be using the same to provide callback functionality to our useState hook to make it function similar to setState. We will be making use of the dependency array of the useEffect to achieve this. If you are not familiar with it, we recommend reading our post on useEffect react hook.