What Is useState() in React - Complete Guide
You may utilize state variables in functional components with the help of the useState Hook. This function takes in the given beginning state as an argument and returns either the current state value or another function that may be used to change it.
This article will show you how to utilize the useState Hook in React, which is similar to this.state and this.setState in other languages. The following topics will be discussed in length:
- React's Class Components and Functional Parts
- Explain the function of the React.useState hook.
- Preserving State in React
- Toggle Hooks: Modify the current state
- The useState hook allows an object to be used as a state variable.
- This section will show you how to use React's Hooks to modify the state of an object within another object.
- An item with several states or multiple states with a single object
- Guideline for utilizing useState
- The application
- Shortening Hook
The video instruction below is a great resource for anybody who is new to React Hooks and would need some visual assistance getting started.
React's Class Components and Functional Parts
In React, you'll find two distinct kinds of parts: class components and functional components.
A class component is an ES6 class that derives from the React framework.
both components and their lifecycles may have states and methods:
class Message extends React.Component {
constructor(props) {
super(props);
this.state = {
message: ‘’
};
}
componentDidMount() {
/* ... */
}
render() {
return <div>{this.state.message}</div>;
}
}
Functions that take in data as properties and return valid JSX are called functional components.
function Message(props) {
return <div>{props.message}</div>
}
// Or as an arrow function
const Message = (props) => <div>{props.message}</div>
This shows that there are no state or lifecycle methods. The usage of Hooks was formerly unavailable, however this has changed as with React 16.8.
Hooks in React are functions that instrument the lifecycle methods of classes and add state variables to functional components. In most cases, they emerge after some period of use.
In what ways is the React.useState Hook useful?
As was previously said, useState lets you include state into functional building blocks. Please respond. By using useState within a function component, a new piece of state may be created that is specific to that component.
In contrast to classes, where state is always an object, Hooks allow for state of any kind. An individual value of any conceivable kind is stored in each state item, which may be an object, an array, a boolean, or anything else.
So, when is the best time to utilize the useState Hook? Managing the state of locally deployed components is a strong suit, but for bigger projects, other state management solutions may be necessary.
Preserving State in React
React provides a branded export called useState. The following is an example of its use in a sentence:
React.useState
Or to import it just write useState:
import React, { useState } from 'react';
But unlike the state object that you can declare in a class, which allows you to declare more than one state variable, like this:
import React from 'react';
class Message extends React.Component {
constructor(props) {
super(props);
this.state = {
message: '',
list: [],
};
}
/* ... */
}
A single state variable (of any type) may be declared using the useState Hook.
import React, { useState } from 'react';
const Message= () => {
const messageState = useState( '' );
const listState = useState( [] );
}
As an argument, useState requires the starting value of the state variable.
If the initial state is the result of a costly operation, you may either supply it directly like in the preceding example, or you can use a function to lazily initialize the variable:
const Message= () => {
const messageState = useState( () => expensiveComputation() );
/* ... */
}
Only on the first render (or only if it's a function) will the initial value be set.
The parameter of the useState Hook is disregarded in future renders (due to a change in the state of the component or a parent component), and the current value is obtained instead.
Keep this in mind if, for instance, you need to modify the component's state in response to newly received properties:
const Message= (props) => {
const messageState = useState( props.message );
/* ... */
}
The problem with relying only on useState is that its argument is only used once, and not whenever the property changes (look here for the right way to do this).
UseState, however, does not just return a variable as the examples above suggest.
It yields a two-element array, the first of which is the state variable, and the second of which is a function that may be used to change the value of the variable:
const Message= () => {
const messageState = useState( '' );
const message = messageState[0]; // Contains ''
const setMessage = messageState[1]; // It’s a function
}
Usually, you’ll use array destructuring to simplify the code shown above:
const Message= () => {
const [message, setMessage]= useState( '' );
}
This way, you can use the state variable in the functional component like any other variable:
const Message = () => {
const [message, setMessage] = useState( '' );
return (
<p>
<strong>{message}</strong>
</p>
);
};
When called, useState should not return an array.
The reason being that arrays are more versatile and user-friendly than objects.
Easily assigning unique names to fields would be difficult if the method always returned an object with the same predefined set of properties.
Assuming the object's properties are state and setState, you'd need to perform something like this:
// Without using object destructuring
const messageState = useState( '' );
const message = messageState.state;
const setMessage = messageState
// Using object destructuring
const { state: message, setState: setMessage } = useState( '' );
const { state: list, setState: setList } = useState( [] );
Change the state using react hooks
Use the method that accepts a new value to update the state variable that is the second item returned by useState.
The state variable is automatically updated whenever the text in the following box is modified.
const Message = () => {
const [message, setMessage] = useState( '' );
return (
<div>
<input
type="text"
value={message}
placeholder="Enter a message"
onChange={e => setMessage(e.target.value)}
/>
<p>
<strong>{message}</strong>
</p>
</div>
);
};
This update function, however, does not instantaneously reflect the new value.
Instead, it puts the process of updating into a queue. The function's most recent value will be returned once the component is re-rendered, regardless of the value passed into useState.
If you want to modify the state based on the previous value, you need to provide a function that takes in the old value and returns the new one.
const Message = () => {
const [message, setMessage] = useState( '' );
return (
<div>
<input
type="text"
value={message}
placeholder="Enter some letters"
onChange={e => {
const val = e.target.value;
setMessage(prev => prev + val)
} }
/>
<p>
<strong>{message}</strong>
</p>
</div>
);
};
The useState hook allows an object to be used as a state variable.
When working with objects, there are two aspects of changes that must be remembered:
- Value of invariability
- In addition, unlike setState(), the setter given by useState does not perform an object merging when used in conjunction with class components.
Regarding the first issue, React will not force a re-render if the updated state has the same value as the current state (React utilizes Object.is for comparison).
It's simple to make the following error while dealing with objects:
const Message = () => {
const [messageObj, setMessage] = useState({ message: '' });
return (
<div>
<input
type="text"
value={messageObj.message}
placeholder="Enter a message"
onChange={e => {
messageObj.message = e.target.value;
setMessage(messageObj); // Doesn't work
}}
/>
<p>
<strong>{messageObj.message}</strong>
</p>
</div>
);
};
In contrast to other examples, the one above modifies the current state object. That's the same thing for React to use.
For this to function, a new thing must be made:
onChange={e => {
const newMessageObj = { message: e.target.value };
setMessage(newMessageObj); // Now it works
}}
The method supplied by useState does not automatically merge update objects when updating a state variable, unlike this.setState in a class component.
In the same vein as before, if we give the message object an additional attribute called id:
const Message = () => {
const [messageObj, setMessage] = useState({ message: '', id: 1 });
return (
<div>
<input
type="text"
value={messageObj.message}
placeholder="Enter a message"
onChange={e => {
const newMessageObj = { message: e.target.value };
setMessage(newMessageObj);
}}
/>
<p>
<strong>{messageObj.id} : {messageObj.message}</strong>
</p>
</div>
);
};
Conclusion
For state variables to be used in functional components, useState may be called as a Hook (function). This function takes in the given beginning state as an argument and returns either the current state value or another function that may be used to change it.