Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Access Callback Like in setState from useState Hook

Has anyone managed to create a sync callback for the update piece of the useState hook in react 16.8? I have been looking for one so that I can deal with synchronous actions with a 3rd party library and I can't seem to make one work for my needs.

If anyone has any references to people that have successfully completed this please add them here.

Cheers,

like image 913
Josh Bowden Avatar asked Mar 06 '19 15:03

Josh Bowden


People also ask

How do you pass callback on setState hooks?

If you have started to use React's useState hook for your application, you may be missing a callback function, because only the initial state can be passed to the hook. In React class components, the setState method offers an optional second argument to pass a callback function.

Can you use callback in useState?

We cannot use callback directly in the useState hook. To use callback in the useState hook, we need to use the useEffect hook that triggers after state update and call the function after that. We need to pass state in the useEffect Dependency Array.

Does setState hook have callback?

setState allows a second parameter to be passed to it as a callback. The callback function is invoked whenever the state of the function gets updated. But, this callback mechanism does not exist with functional components.

How do you use callbacks in React hooks?

The useCallback hook is used when you have a component in which the child is rerendering again and again without need. Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed.


2 Answers

With hooks, you no longer need a callback from the setState function. Now, you can set state with the useState hook, and listen for its value to update with the useEffect hook. The optional second parameter of the useEffect hook takes an array of values to listen to for changes. In the example below, we are just monitoring one value for changes:

const Example = () => {
  const [value, setValue] = useState(null);

  useEffect(() => {
    // do something when value changes
  }, [value]);

  return (
    <button onClick={() => setValue('Clicked!')}>
      Click Me!
    </button>
  );
};

Read more about the useEffect hook here.

like image 77
Don Brody Avatar answered Oct 23 '22 07:10

Don Brody


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 are looking for an out of the box solution, check out this custom hook that works like useState but accepts as second parameter a callback function:

import useStateWithCallback from 'use-state-with-callback';

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

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

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

It can be installed via npm install use-state-with-callback

If you want to make synchrone layout updates, use import { useStateWithCallbackInstant } from 'use-state-with-callback'; instead.

like image 27
Robin Wieruch Avatar answered Oct 23 '22 05:10

Robin Wieruch