The useState Hook in React is used to add state to functional components. It allows you to create state variables and update them within your component.
Basic Usage
The useState Hook takes an initial state value as its argument and returns an array with two elements:
- The current state value.
- A function to update the state value.
Example: Basic Usage
import React, { useState } from 'react';
function Counter() {
// Declare a state variable 'count' with an initial value of 0
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(count - 1)}>Decrement</button>
</div>
);
}
export default Counter;
State Initialization
You can initialize the state with a primitive value, an object, or any other data type.
Example: Initializing State with an Object
import React, { useState } from 'react';
function UserInfo() {
const [user, setUser] = useState({ name: '', age: '' });
const handleNameChange = (e) => {
setUser({ ...user, name: e.target.value });
};
const handleAgeChange = (e) => {
setUser({ ...user, age: e.target.value });
};
return (
<div>
<input type="text" value={user.name} onChange={handleNameChange} placeholder="Name" />
<input type="number" value={user.age} onChange={handleAgeChange} placeholder="Age" />
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
</div>
);
}
export default UserInfo;
Functional Updates
If the new state depends on the previous state, you can pass a function to setState which receives the previous state and returns the new state.
Example: Functional Update
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(prevCount => prevCount + 1);
};
const decrement = () => {
setCount(prevCount => prevCount - 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}
export default Counter;
Lazy Initialization
If the initial state is the result of an expensive computation, you can pass a function to useState which will only be called during the initial render.
Example: Lazy Initialization
import React, { useState } from 'react';
function ExpensiveComponent() {
const computeInitialValue = () => {
// Expensive computation
return 42;
};
const [value, setValue] = useState(() => computeInitialValue());
return <div>Value: {value}</div>;
}
export default ExpensiveComponent;
Multiple State Variables
You can use multiple useState calls to handle different pieces of state within the same component.
Example: Multiple State Variables
import React, { useState } from 'react';
function Form() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
return (
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name"
/>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
/>
<p>Name: {name}</p>
<p>Email: {email}</p>
</div>
);
}
export default Form;
Important Points
- Immutability: State updates should be treated as immutable. Always create a new object or array instead of mutating the existing state directly.
- Batched Updates: React batches state updates for performance improvements. Multiple state updates in the same event handler will result in a single re-render.
- Component Re-renders: Updating state triggers a re-render of the component. Ensure that the state updates are necessary to avoid unnecessary re-renders.
By understanding and using useState effectively, you can manage state in your functional components efficiently and clearly.
