Introduction
There are two types of component in React-native class component
& Functional component
.
useState
is a hook that allows a functional component to store state variable. If you are working with class component
, It is equivalent to this.state/ this.setState
. In this article we will try to understand the basic concept of useState
.
Alright, let's get started !!
The Traditional way of managing state
In Class component
, we have a property state
for reading the state(hold the state) and setState
property that can we used for updating the states. Whenever we update the state it triggers the render
method.
export default class ButtonClick extends Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
render() {
return (
<View>
<Text>You have clicked this {this.state.count} time(s)</Text>
<Button
title="Click"
onPress={() => this.setState({count: this.state.count + 1})}></Button>
</View>
);
}
}
UseState()
Functional component are just a functions that accept the properties as parameter and returns a valid JSX. Functional component does not have state or any lifecycle method. useState
provides the facility of managing states in functional component.
Anatomy of useState()
The useState()
hook sets up an individual state property. It returns an array containing two elements: the current state value, and a function you can call with a new value to update the state.
Declaring the useState()
Import the useState() package from react
import React, {useState} from 'react';
Initialising the state
The first argument of useState(initialState) is the initial state.
const count = useState(0);
Reading the state
As we know useState() returns an array, whose first element is the current state.
<Text style={{fontSize: 30}}>{count[0]}</Text>
For the shake of readability, we prefer array destructuring .
For initialisation,
const [count, setCount]= useState(0);
For Reading the state,
<Text style={{fontSize: 30}}>{count[0]}</Text>
Updating the State
Updating the states with a value
As we know that useState() return an array whose second item is a function which can we used for updating the state.
<Button
title="Click Me"
onPress={() => {
setCount(8);
}}
/>
Updating the states with a callback
Sometimes there is a scenario, we have to calculate the next state on the basis of previous state, we can update the state with callback.
<Button
title="Click Me"
onPress={() => {
setCount(previousCount => previousCount + 1);
}}
/>
Using object as state variable
We can also initialise and update the object with the useState()
const [userInfo, setUserInfo] = useState({name: 'Raj', age: 27});
For updating the the value we can try this.
const [userInfo, setUserInfo] = useState({name: 'Raj', age: 27});
const name = userInfo.name;
const age = userInfo.age;
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text style={{fontSize: 12}}>
My Name is {name}. I am {age} years old
</Text>
<Button
title="Update Info Me"
// It will not merge the object. It will just override the state.
onPress={() => {
setUserInfo(previous => {
return {age: previous.age + 1};
});
}}
/>
</View>
);
When we will click on the Button
, you will notice something interesting. Our age
will be incremented by one which is correct but the name
property is totally disappeared. So this is the problem with the useState()
, it does not merge the object like we have seen in class component when we call this.setState
. Actually It is overriding the object with current state.
If we really want to update the object, firstly we have to spread out the previous object and then update it. It will look something like that.
onPress={() => {
setUserInfo(previous => {
// We can use spread operator
return {...previous, age: previous.age + 1};
});
}}
Multiple States
When working with multiple fields or values as the state of your application, you have the option of organising the state using multiple state variables.
const [name, setName] = useState('Raj');
const [age, setAge] = useState(27);
Lazy initialisation of useState
Whenever we executes useState(), React re-renders the component. It is fine if the initial value is primitive value. It will not cause any performance issue.
Suppose, If we have to perform any expensive calculation (e.g. calculating fibonacci..) , it may cause performance issue. With the help of lazy initialisation we can overcome from this problem.
We can also pass a function as an argument to useState() for initialising the state.
const [calculateJson, setCalculateJson] = useState(() => {
return {
name: 'Raj',
age: 27,
};
});
Now it will call only first time while rendering.
Rules
- Only call Hooks at top level
- Only call Hooks from the React-Functions.
- If your state depends on previous state try to update using callback.
onPress={() => {
setAge(previous => previous + 1);
}}
Conclusion
This is the basic idea about using useStae(). Let's note down the key point.
-
useState()
makes functional component more powerful by allowing them to the process state. -
useState()
returns an array whose first item is current state and second item is a function which is used for updating the state. -
useState(initialParam)
takes the initial value of the state variable as an argument. - We can update the state by passing a value or using a callback.
- Whenever we call useState(), React will re-render the component
- If we want to perform expensive calculation while initialising the state, we can do this by passing initial state as a function in
useState(()=>{})
. By doing so render will called only once. -
useState()
does not auto merge the objects . We can achieve this with the help of spread operator.
Thanks for reading this article. Feel free to add your suggestions. You can connect with me at Twitter.
Stay safe !!
Top comments (0)