Introduction
Hey,
UseState is a method that allows you to maintain the local state in the component. It has a very simpler syntax. We can update the state through only one function. So, we can overcome a lot of unwanted bugs and data mutating issues. So in this blog, I almost cover how to use, good and bad practices with small examples.
Let’s get going.
What is Hooks?
We could say, Hooks are utility functions. Using this, we can write clean and maintainable code. This makes developer life easier.
Note: React Hooks can be used only on functional components. Nevertheless, class components have their own way to maintain the state.
What is useState?
useState() is a method to maintain the Local state in the component. The state value is empty by default.
Note: React Hooks can be used only on functional components. Nevertheless, class components have their own way to maintain the state. The class component state looks like,
class Profile extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'xyz'
email: 'xyz@gmail.com'
};
}
}
We can initialize the state using useState method.
useState('Initialized value');
Why can we use this?
State is always immutable. While updating the state, behind the scenes, it will create a new reference(instead, It doesn't mutate with the existing object) and assign it to the current state variable.
Whenever the state changes, the component will be re-rendered. So we can update the latest data in the view. but if we are not using the state, the component will be triggered once(Initial render). So using this way, it is really difficult to update the view.
How to use?
Before using the state, We can import the useState method from 'react'.
import React, { useState } from "react";
export default function Profile() {
const [profile, updateProfileState] = useState({
name: 'xyz',
email: 'xyz@gmail.com',
});
function updateEmail(email) {
updateProfileState((prevState) => {
return { ...prevState, email };
});
}
return (
<React.Fragment>
<h1>Name: {profile.name}</h1>
<h1>Email: {profile.email}</h1>
<button onClick={() => updateEmail('example@gmail.com')}>
Update Email
</button>
</React.Fragment>
);
}
The useState method returns an array of two elements. Here, profile would be used to refer to the current state(That always holds the current state value), and updateProfileState is a function to update the state.
We have a small JSX expression to show the name, email, and update button in UI. Basically, our goal is to update the email into the state.
function updateEmail(email) {
updateProfileState((prevState) => {
return { ...prevState, email };
});
}
We're using a small function (updateEmail) to update the state. While updating the state, we have to use the previous state value(prevState) and the current property value(email).
function updateEmail(email) {
updateProfileState({ email: email });
}
If we are not using the previous state, we can lose some properties from the profile object. That is not a good practice also.
We can use the useState method more than once to maintain the different states in a component as mentioned below.
export default function UserList() {
const [profile] = useState({
name: 'xyz',
email: 'xyz@gmail.com',
});
const [roles] = useState([
{
name: 'xyz',
role: 'admin',
},
{
name: 'abc',
role: 'contentAdmin',
},
]);
}
Then, If we want to manage the single state for both parent and child components, that is also possible. But If we want to update the state, we have to send the callback to the parent component and update the state.
Good and bad practices
- useState method should be called only on the top level of react function. So useState method will be executed in the same order.
export default function Example() {
//Initialized the States in the top level of React function
useState(1);
useState(2);
useState(3);
useState(4);
// Add a function to update the State
function update() {}
update();
// JSX expression to display the content in the view.
return <div>Welcome to React</div>;
}
Note: Don't declare a hook inside an if condition, for loops, and, inside a normal javascript function. Basically, it will throw an error while compiling the code.
export default function Example() {
/**
* React is not recommended to initialize the useState hook-like below.
*/
if (true) useState(1);
function customState() {
useState(4);
}
customState();
return <div>Welcome to React</div>;
}
React provides two ways to initialize the state.
Mostly we can use this way to initialize the state. We can go with this approach if we are initializing static numbers or strings. if we have objects or arrays just go with the function version of initializing state. The reason I've mentioned below.
useState('state initialized');
The second way is to be, We’ve to use the function version to initialize the state. The main idea to go with this approach is that, whenever the state changes, the component will be re-rendered again. At the same time, the useState method is also triggered while state changes. if we are computing a complex logic, it might have taken some time to finish the execution. So every state changes, our complex logic will be executed. So it leads to performance issues.
export default function Example() {
useState(() => {
return [
{
name: 'A',
},
{
name: 'B',
},
{
name: 'C',
},
];
});
return <div>Welcome to React</div>;
}
Finally, I've attached the sample code which I worked with the useState hook. React-UseState