The purpose of this article is to break down the use of the useState() React hook in an easy way using strings, objects, and arrays. We will also take a look at how these would be handled in class components.
Disclaimer - I would normally create an onChange function separately but I find it easier to understand with an inline function.
What is the setState function?
The setState
function is used to handle the state object in a React class component. This is something you will see a lot of in the examples below. Anytime you see a this.setState()
this is how we are setting the state in a class component.
What is a hook in React?
React hooks were introduced in React v16.8. They allow you to use state and other React features without the need to create a class.
Examples:
Class component
Functional component
While these two code snippets look similar they do have slight differences in syntax, lifecycle methods, and state management.
setState() vs useState() - Strings.
- setState() Class Component
Using state in a class component requires the building of a state object. This state object is then modified by calling this.setState("new state").
In this example, we've created a state = { value: '' }
object which has a value
key and that key is initialized as an empty string. We've assigned an onChange
event to the input so that every time we add or remove a character to the input we are calling the this.setState()
. Here we areupdating the state using the value of the input (e.target.value
) and setting it to the components state.
- useState() Functional Component
With a functional component, we can use React hooks, specifically the useState()
hook. This simplifies the creation of a state component and the function that updates it.
We import {useState}
from React and we are able to simply create a state and a function to set that state (state: value
, setState: setValue
). The initial state of this component is set when calling useState
, in this example, we are setting it to an empty string (useState("")
). The only difference between the functional component and the class component at this point is instead of calling this.setState
we use the function we created in the useState
, in this case, setValue
.
setState() vs useState() - Objects.
- setState() Class Component
Since state
in a class component is already an object, it's business as usual. Use setState
to populate the values of the state object.
With the example above the users userName
and email
is stored in the state similar to the string version we talked about above.
- useState() Functional Component
When we want to use the useState
hook for an object we are going to initialize it to an empty object useState({})
.
In this example, we are using the same setValue
that we did in the string example but we've added a few things to our setValue
function. First, we use the spread syntax to expand the current value
before we add a new key-value pair. Second, we dynamically set the key using [e.target.name]
, in this case, we are creating the key using the input's "name" attribute. Lastly, we are setting that key's value to the e.target.value
. So after using the inputs we have an object with two keys {userName: "", email: ""}
and their values.
Creating an object could also be accomplished using multiple useState
hooks and then bundling them into an object later if needed. See the example below.
Note: I have my own preference for how to deal with objects while using hooks, and as you get more familiar you may find you enjoy either the class or functional component more than the other.
setState() vs useState() - Arrays.
Using arrays in stateful components can be extremely powerful, especially when creating things like a todo list. In these examples, we will be creating a very simple todo list.
- setState() Class Component
When using an array in a stateful class component we need at least two keys in our state object. One would be the array itself todoArr: []
and the other would be the value that we are going to be pushing into the array todo: ""
.
In this example, we use the onChange
attribute for our input to set the todo
in our state object. We then have our Add Item
button which when clicked will call our addItem
function. In the addItem
function we are going to create a list variable which is is an array that spreads the current todoArr
and then adds the new todo
item to the end of it. After creating the list array we use the setState
function to replace the current todoArr
with the new one and then set the todo
back to an empty string to clear the input. Lastly at the bottom, we map through the current todoArr
. The setState
function will cause the component to rerender so every time you add an item it is immediately rendered onto the page.
- useState() Functional Component
Dealing with the hooks in a function component seems extremely similar to the class component.
We use the setTodo
function to set our todo
value in the onChange
attribute of our input. We then have the same addItem
function attached to the click of our Add Item button. The only difference we see here is that we don't create a list variable to pass into the hook. We could have avoided this in the class component but I think the readability when using the variable is much better. With the hook, I don't think the use of creating the list
array beforehand is needed. We can spread the current array, add the new item, and then set the current todo
back to an empty string so we can clear the input.
Conclusion
While using functional components with hooks is the new hotness, the state management is still very similar to the class components. If you're looking to start using function components with hooks over class components hopefully this post has helped you understand a little bit more about how to implement them.
Top comments (2)
very clear!
thanks