3

I am a beginner in React and I follow a tutorial in Udemy.I had a confusion about state. When I am trying to update the state depending on the previous state, why the mentor says that we need to always use the second approach while both approaches seems logical to me.

This is my initialization

const [UserInput, setUserInput] = useState({
      enteredTitle:'',
      enteredDate:'',
      enteredAmount:''
  });

So here is the first approach.

const handleTitleChange = (event) =>{
      setUserInput({
          ...UserInput,
          enteredTitle:event.target.value
      })
  }

This is my second approach.

const handleTitleChange = (event) =>{
    setUserInput((prevState) => {
        return{
            ...prevState, enteredTitle:event.target.value}
    });
ClericGame
  • 63
  • 7

2 Answers2

4

Your mentor isn't right. Your first approach can well work in many situations, as you've probably noticed. But there are some in which you do need to use the second approach - namely, when the function, when it gets invoked, might close over an old value of the state. For example, if you have a button that, when clicked, will then change state after 2 seconds - the state may change in those 2 seconds, in which case the UserInput state that the function in the timeout closes over would be out of date.

// Don't do this
const handleClick = () => {
  setTimeout(() => {
    setState({ ...state, newProp: 'newVal' });
  }, 2000);
};

Using the callback form instead - setState(state => or setUserInput((prevState) => - is necessary when you don't have a reliably up-to-date state variable already in scope.

Many prefer to use the simple state setter method - eg

  setUserInput({
      ...UserInput,
      enteredTitle:event.target.value
  })

and avoid the callback version unless situation calls for the callback version. It's less code to write, read, and parse.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
0

export default function App() { const [counter, setCounter] = React.useState(0);

function incrementCounterHandler() {
    setCounter(prevCounter => prevCounter + 1);
}

return (
  <div>
    <p id="counter">{counter}</p>
    <button onClick={incrementCounterHandler}>Increment</button>
  </div>
);

}

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 28 '23 at 04:43