How to use `setState` callback on react hooks

You need to use useEffect hook to achieve this.

const [counter, setCounter] = useState(0);

const doSomething = () => {
  setCounter(123);
}

useEffect(() => {
   console.log('Do something after counter has changed', counter);
}, [counter]);

If you want the useEffect callback to be ignored during the first initial render, then modify the code accordingly:

import React, { useEffect, useRef } from 'react';

const [counter, setCounter] = useState(0);
const didMount = useRef(false);

const doSomething = () => {
  setCounter(123);
}

useEffect(() => {
  // Return early, if this is the first render:
  if ( !didMount.current ) {
    return didMount.current = true;
  }
  // Paste code to be executed on subsequent renders:
  console.log('Do something after counter has changed', counter);
}, [counter]);

Mimic setState callback with useEffect, only firing on state updates (not initial state):

const [state, setState] = useState({ name: "Michael" })
const isFirstRender = useRef(true)
useEffect(() => {
  if (isFirstRender.current) {
    isFirstRender.current = false // toggle flag after first render/mounting
    return;
  }
  console.log(state) // do something after state has updated
}, [state])

Custom Hook useEffectUpdate

function useEffectUpdate(callback) {
  const isFirstRender = useRef(true);
  useEffect(() => {
    if (isFirstRender.current) {
      isFirstRender.current = false; // toggle flag after first render/mounting
      return;
    }
    callback(); // performing action after state has updated
  }, [callback]);
}

// client usage, given some state dep
const cb = useCallback(() => { console.log(state) }, [state]); // memoize callback
useEffectUpdate(cb);