skip to Main Content

I read the posting and something I can’t understand is the difference between setValue(curr + 1) and setValue(prev => prev + 1)
Is there anybody who can give me an example in reality so that I can test it on my side?
He called setValue inside the event handler, but what if I call it in another?
Is it a good practice for me to use latter one whenever I use useState?

https://levelup.gitconnected.com/4-usestate-mistakes-you-should-avoid-in-react-0d9d676869e2

2

Answers


  1. The setValue(value + 1) is usually used when the current state is not dependent on the previous start, like updating the name.

    And this setValue((value) => value+1) is used when the current state is dependent on the previous start.

    Below is an example,

    import React, { useState } from 'react';
    
    function Counter() {
      const [value, setValue] = useState(0);
    
      const handleDirectUpdate = () => {
        setValue(value + 1);
        setValue(value + 1);
      };
    
      const handleFunctionalUpdate = () => {
        setValue(prev => prev + 1);
        setValue(prev => prev + 1);
      };
    
      return (
        <div>
          <p>Value: {value}</p>
          <button onClick={handleUpdate}>Direct Update</button>
          <button onClick={handleFuncUpdate}>Functional Update</button>
        </div>
      );
    }
    
    export default Counter;
    Login or Signup to reply.
  2. I hope this helps

    The difference between setValue(curr + 1) and setValue(prev => prev + 1) in a React component using useState lies in how they update the state.

    setValue(curr + 1)

    This approach directly uses the current value of curr to set the new state. For example:

    const [value, setValue] = useState(0);
    
    const handleClick = () => {
      const curr = value;
      setValue(curr + 1);
    };
    

    Here, curr is the current state value when the handleClick function is called. This approach works fine in simple scenarios but can lead to issues if the state updates happen asynchronously or if there are multiple updates in a short period.

    setValue(prev => prev + 1)

    This approach uses a function that receives the previous state value (prev) and returns the new state. For example:

    const [value, setValue] = useState(0);
    
    const handleClick = () => {
      setValue(prev => prev + 1);
    };
    

    This method is generally safer and more predictable because it ensures that the state update is based on the most recent state value, even if multiple updates are queued.

    Example to Test

    Here’s a simple example you can run to see the difference:

    import React, { useState } from 'react';
    
    function Counter() {
      const [value, setValue] = useState(0);
    
      const handleDirectUpdate = () => {
        const curr = value;
        setValue(curr + 1);
        setTimeout(() => {
          setValue(curr + 1); // This may not work as expected because `curr` might be stale.
        }, 1000);
      };
    
      const handleFunctionalUpdate = () => {
        setValue(prev => prev + 1);
        setTimeout(() => {
          setValue(prev => prev + 1); // This will always work as expected.
        }, 1000);
      };
    
      return (
        <div>
          <p>Value: {value}</p>
          <button onClick={handleDirectUpdate}>Direct Update</button>
          <button onClick={handleFunctionalUpdate}>Functional Update</button>
        </div>
      );
    }
    
    export default Counter;
    

    Explanation

    • Direct Update (handleDirectUpdate):

      • When you click the "Direct Update" button, it sets value to curr + 1 immediately.
      • After 1 second, it tries to set value to curr + 1 again. However, curr might be stale (not the latest state value), so the second update may not work as expected.
    • Functional Update (handleFunctionalUpdate):

      • When you click the "Functional Update" button, it sets value to prev + 1 immediately.
      • After 1 second, it sets value to prev + 1 again using the most recent state value. This approach ensures that the state is correctly incremented regardless of the timing.

    Good Practice

    It is generally a good practice to use the functional form (setValue(prev => prev + 1)) whenever you need to update state based on the previous state value. This approach is more robust and handles asynchronous state updates more reliably.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search