The useState hook is a fundamental concept in React for handling local component state. It helps you remember things like form values, counters, toggle states, etc., while the component is being rendered and re-rendered.
import { useState } from 'react';
function MyComponent() {
const [state, setState] = useState(initialValue);
// ...
}
const [state, setState] = useState(initialValue)state) to read the current valuesetState) to update the value// Direct update
setState(newValue);
// Update based on previous state
setState(prevState => prevState + 1);
const [user, setUser] = useState({ name: '', email: '' });
// ❌ INCORRECT: Direct mutation
user.name = 'John';
// ✅ CORRECT
setUser({ ...user, name: 'John' });
const [items, setItems] = useState([]);
// Add
setItems(prev => [...prev, newItem]);
// Remove
setItems(prev => prev.filter(item => item.id !== idToRemove));
// Update
setItems(prev => prev.map(item => item.id === idToUpdate ? { ...item, name: 'Updated' } : item));
const [inputValue, setInputValue] = useState('');
const handleChange = (e) => {
setInputValue(e.target.value);
};
// In JSX
<input value={inputValue} onChange={handleChange} />
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: value
}));
};
// In JSX
<input name="firstName" value={formData.firstName} onChange={handleChange} />
// ✅ GOOD
const [name, setName] = useState('');
const [age, setAge] = useState(0);
// ❌ NOT IDEAL
const [person, setPerson] = useState({ name: '', age: 0 });
const [formData, setFormData] = useState({
username: '',
password: '',
email: ''
});
// ❌ RISKY
setCount(count + 1);
// ✅ SAFE
setCount(prevCount => prevCount + 1);
// ❌ BAD
const [firstName, setFirstName] = useState('John');
const [lastName, setLastName] = useState('Doe');
const [fullName, setFullName] = useState('John Doe');
// ✅ GOOD
const [firstName, setFirstName] = useState('John');
const [lastName, setLastName] = useState('Doe');
const fullName = `${firstName} ${lastName}`;
// ❌ NOT IDEAL
const [data, setData] = useState(createExpensiveObject());
// ✅ GOOD
const [data, setData] = useState(() => createExpensiveObject());
setState(newValue);
console.log(state); // Still the old value!
useEffect(() => {
console.log(state); // Now updated!
}, [state]);
// Class Component
this.setState({ name: 'John' });
// Functional Component
setUser({ name: 'John' }); // Removes other props!
setUser(prev => ({ ...prev, name: 'John' }));
Every time you call a state setter function, React re-renders the component unless the new state is the same as the previous one.