2

What is the best practice to replace the usage of setState function from React.Component -- https://reactjs.org/docs/react-component.html#setstate

setState(updater, [callback])

where updater has the signature

(state, props) => stateChange

(So the new state depends on previous state and also props)

-- using React hooks?

When I searched for the useState hook's API, https://reactjs.org/docs/hooks-reference.html#functional-updates

Functional updates If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value. Here’s an example of a counter component that uses both forms of setState:

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}

the function updating the state, setCount, does not take props as an argument.

Is the best practice for this to use useEffect hook, with props as a dependency?

Could anyone explain why this was separated in the React hooks?

jpz
  • 165
  • 1
  • 6

2 Answers2

0

The Hooks FAQ has a section on How do I implement getDerivedStateFromProps?. While it first says generally you probably won't need derived state from props, it then goes on to give an example of referencing props via closure, i.e. just references them directly.

So I believe a combination of referencing the prop directly with the set state function argument should work, like:

export default function Conuter({ incrementBy }) {
  const [count, setCount] = useState(0)
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(prevCount => prevCount + incrementBy)}>
        Increase count by increment
      </button>
      <button onClick={() => setCount(0)}>Reset</button>
    </>
  );
}

Live example here.

Hugo
  • 334
  • 3
  • 10
-1

In short, yes, it is perfectly safe to use setCount(count + 1), and this is the usual practice for setting of state for functional components.

If you are looking for the callback pattern, I believe this other SO post will be more suited to answer your question, as they are utilising the useEffect hook for that purpose.

wentjun
  • 40,384
  • 10
  • 95
  • 107
  • I think you've slightly missed the point my question. The usage I'm questioning about is for updating the state not only based on the previous state value, but also with the value in props. – jpz Apr 16 '20 at 02:24
  • @jazzinpark ahh.. ok I get your question now. You can still do something like this? `setCount(count + props.count)`? – wentjun Apr 16 '20 at 08:42
  • Wouldn't this be an anti-pattern, with the similar reason stated in [State Updates May Be Asynchronous](https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous)? I'm not sure though. – jpz Apr 16 '20 at 11:52
  • I think it should be fine, because count is a primitive type, right? `number`? I doubt there will be any weird mutations – wentjun Apr 16 '20 at 13:07