We help IT Professionals succeed at work.

Can I have a simplified explanation of how useState works?

I'm [new to / learning] react and so I'm experimenting with code samples that I find and trying to understand concepts within the language. Why does this work when the button is clicked:

import React, { useState } from 'react';


const Home = props => {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  const manipulateSomeState = () => {
        setCount(() => (count + 1));
  };

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={manipulateSomeState}>
        Click me
      </button>
    </div>
    );
}

export default Home;

Open in new window


But this does not work when the button is clicked:
import React, { useState } from 'react';


const Home = props => {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  const manipulateSomeState = () => {
        setCount({count: count + 1});
  };

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={manipulateSomeState}>
        Click me
      </button>
    </div>
    );
}

export default Home;

Open in new window


If I can get an explanation in "laymen" (non technical) terms that would be great.  Everything is the same except the "manipulateSomeState" function within the functional component. For what its worth, when I look at the first version of the manipulateSomeState function (the one that breaks/doesn't work) it seems straight forward. In my mind I'm adding 1 to the count state variable. In the second version of manipulateSomeState (the version that works), it seems like I'm having to use an anonymous function to accomplish the same thing and it appears to me that this is more/overly complicated. What am I not understanding.



Thanks in advance.
Comment
Watch Question

Michael SterlingWeb Applications Developer

Author

Commented:
After talking with a co-worker I was offered this: This code:

setCount({count: count + 1});

Open in new window


converts the parameter in the setCount function into an object and there for the function doesn't know what to do with it and that's why it blows up.

This code:
setCount( () => count + 1 );

Open in new window

and or this code:
setCount(count + 1 );

Open in new window

achieves the desired result because in both cases, its taking the current value of the count state variable and just incrementing it. Can anyone add any more depth/info to this explanation? I do understand, but I'm just looking of other ways of understanding it.
Most Valuable Expert 2018
Distinguished Expert 2019
Commented:
Hi Michael,

useState() is known as a hook. Let's take a look at this line:

const [count, setCount] = useState(0);

It does several things. It declares a state variable called count. It declares a function that allows you to update that variable (setCount) and it sets a starting value for that variable (0).

Once you've ran that line you can call the function to update the variable:

setCount(5);
setCount(7+2);

You can of course call that function whatever you like:

const [count, updateMyCount] = useState(0);
...
updateMyCount(12);

The reason your code blew up, as you rightly said, is because you're trying to pass an object into that method instead of a scalar value. I think where the confusion lies is down to the use of the built in setState() method. Let's say you'd set up your state like so:

state = {
    count: 0
}

Then you would pass an object into setState, with the key set to the property's name:

setState( { count : count + 1 } );
setState( { count : 15 } );
Michael SterlingWeb Applications Developer

Author

Commented:
@Chris: Thanks for taking the time to add to this discussion.