Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - Is useState 's setter function able to change?

Is useState's setter able to change during a component life ?

For instance, let's say we've got a useCallback which will update the state. If the setter is able to change, it must be set as a dependency for the callback since the callback use it.

const [state, setState] = useState(false);
const callback = useCallback(
    () => setState(true),
    [setState] // <-- 
);
like image 804
Yairopro Avatar asked Jul 24 '19 10:07

Yairopro


People also ask

What does useState setter return?

Using the useState State Setter Function Properly We call the useState hook to return the setCount function to set the state. And we call setCount with a callback that takes the previous state value and return the new state value based on that. The useEffect callback runs when count 's value is changed.

Why React useState setState does not update immediately?

If you find that useState / setState are not updating immediately, the answer is simple: they're just queues. React useState and setState don't make changes directly to the state object; they create queues to optimize performance, which is why the changes don't update immediately.

How do I update my useState value in React?

push(1); However, with React, we need to use the method returned from useState to update the array. We simply, use the update method (In our example it's setMyArray() ) to update the state with a new array that's created by combining the old array with the new element using JavaScript' Spread operator.

Are Usestates better than useState objects?

1 useState with atom is slightly better than with object because we skip object allocation. useState calls are more expensive than object allocations, so for 3+ items useState(object) wins.


2 Answers

The setter function won't change during component life.

From Hooks FAQ:

(The identity of the setCount function is guaranteed to be stable so it’s safe to omit.)

The setter function (setState) returned from useState changes on component re-mount, but either way, the callback will get a new instance.

It's a good practice to add state setter in the dependency array ([setState]) when using custom-hooks. For example, useDispatch of react-redux gets new instance on every render, you may get undesired behavior without:

// Custom hook
import { useDispatch } from "react-redux";

export const CounterComponent = ({ value }) => {
  // Always new instance
  const dispatch = useDispatch();

  // Should be in a callback
  const incrementCounter = useCallback(
    () => dispatch({ type: "increment-counter" }),
    [dispatch]
  );

  return (
    <div>
      <span>{value}</span>

      // May render unnecessarily due to the changed reference
      <MyIncrementButton onIncrement={dispatch} />

      // In callback, all fine
      <MyIncrementButton onIncrement={incrementCounter} />
    </div>
  );
};
like image 137
Dennis Vash Avatar answered Oct 22 '22 23:10

Dennis Vash


The short answer is, no, the setter of useState() is not able change, and the React docs explicitly guarantee this and even provide examples proving that the setter can be omitted.

I would suggest that you do not add anything to the dependencies list of your useCallback() unless you know its value can change. Just like you wouldn't add any functions imported from modules or module-level functions, constant expressions defined outside the component, etc. adding those things is just superfluous and makes it harder to read your handlers.

All that being said, this is all very specific to the function that is returned by useState() and there is no reason to extend that line of reasoning to every possible custom hook that may return a function. The reason is that the React docs explicitly guarantee the stable behavior of useState() and its setters, but it does not say that the same must be true for any custom hook.

React hooks are still kind of a new and experimental concept and we need to make sure we encourage each other to make them as readable as possible, and more importantly, to understand what they actually do and why. If we don't it will be seen as evidence that hooks are a "bad idea," which will prohibit adoption and wider understanding of them. That would be bad; in my experience they tend to produce much cleaner alternatives to the class-based components that React is usually associated with, not to mention the fact that they can allow organizational techniques that simply aren't possible with classes.

like image 27
BHarms Avatar answered Oct 22 '22 23:10

BHarms