Josh Bowden
Josh Bowden

Reputation: 1342

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,

Upvotes: 12

Views: 11860

Answers (2)

Don Brody
Don Brody

Reputation: 1717

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.

Upvotes: 16

Robin Wieruch
Robin Wieruch

Reputation: 15898

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.

Upvotes: 3

Related Questions