Amit
Amit

Reputation: 4353

is the useState's setter guaranteed to be the same?

Say I want to create the often wanted useInputState hook:

function useInputState(initialValue) {
  const [value, setValue] = useState(initialValue);
  const onChange = useCallback(
    e => setValue(e.target.value), 
    [ /* ??? */ ]
  );
  return { value, onChange };
}

Would I need to add the setValue setter function to the callback's dependencies? Can we count on the setter to always stay the same? This seems to work when I try it, but is this good practice? Or should we assume ANYTHING in the callback's closure can change and affect its implementation?

(I can think of more examples that eventually raise the same question)

Upvotes: 6

Views: 693

Answers (2)

Estus Flask
Estus Flask

Reputation: 222354

Yes, useState state setter is the same function; even if it wouldn't, it would be expected to update the state. It is supposed to be used like the question shows.

The common usage is explained better in useReducer documentation:

useReducer also lets you optimize performance for components that trigger deep updates because you can pass dispatch down instead of callbacks.

And useState uses useReducer internally.

The concerns with a scope where useState was called are applicable only to useState state value which stays the same in the scope of a callback where it's used, e.g. this problem. In case current state should be used, it should be retrieved with state updater function, like setValue(currentState => currentState + 1).

Upvotes: 1

Ryan Cogswell
Ryan Cogswell

Reputation: 80986

Yes, the setter from useState and similarly the dispatch from useReducer do not change.

This portion of the docs covers the pattern of passing the dispatch method to descendant components via context and contains the following:

If you use context to pass down the state too, use two different context types — the dispatch context never changes, so components that read it don’t need to rerender unless they also need the application state.

Upvotes: 3

Related Questions