skip to Main Content

i have the following code :

function Usestatedemo() {
  const abc = useState(5);

  const count = abc[0];
  const setcount = abc[1];
  const changeit = () => {
    count = count + 1; // error here in setting value to count
    setcount(count + 1); // no error here
  };
  return (
    <div>
      Usestatedemo
      <button onClick={changeit}>click</button>
      {count}
    </div>
  );
}

While i am not able to change the value of count directly ,but can change through setcount method. Why this so.

3

Answers


  1. When you call setCount, you are not changing the local const count at all. You are just asking react to render your component again. React updates its internal state to store the new value. This internal state is not a const and so can be changed. Then react renders, and your component executes again.

    When your code runs you make a brand new local const named count. It may have the same name as the previous one, but it’s a completely new variable. It is not restricted to having the same value as the old one. useState returns a snapshot of react’s internal state (ie, the new value you asked to set the state to) and you assign the new value to your new count variable.

    Login or Signup to reply.
  2. As I said in the comments – consts are never changed here.

    Usestatedemo is called multiple times, and useState returns a new value every time.

    Changing state makes react rerender the component with new values

    let cache = undefined;
    
    function Usestatedemo() {
      const abc = useState(5);
    
      const count = abc[0];
      const setcount = abc[1];
      const changeit = () => {
        setcount(count + 1);
      };
      // I replaced click and return with this
      setTimeout(changeit, 1000);
      console.log("count is", count);
    }
    
    Usestatedemo();
    
    // use state implementation
    // it's much more complicated in reality
    function useState(initialValue) {
      if (cache === undefined) {
        cache = initialValue;
      }
      return [
        cache,
        (newValue) => {
          if (cache !== newValue) {
            cache = newValue;
            Usestatedemo();
          }
        },
      ];
    }
    Login or Signup to reply.
  3. Of course that’s correct, because you’re not updating the reference of the object itself, you are updating either the value in the index 0, if you deconstruct it as an array; or a property name in the case you deconstruct it as an object (useful in custom hooks).

    In your example abc is the const, but the value it holds is this:

    const abc = [myNumber: number, setMyNumber: (abc:number) => void]
    

    When you try to update abc directly:

    abc = 10
    

    You’re trying to change the reference of the object itself to something completely different, and that’s a no-no.

    But, when you use the setAbc, what it does is update the index 0 of your const, not the const itself.

    I’d suggest deconstructing the useState hook, so you check more clearly what is actually happening.

    This is what I mean with the deconstruction:

    const [myNumber, setMyNumber] = useState(0)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search