State & the useState Hook
Props vs state
You’ve seen props (data passed in, read-only). State is data a component owns and can change over time — a counter, the text in a field, whether a menu is open. When state changes, React re-renders the component to show the new value.
useState
The useState hook adds state to a function component. It returns the current value and a function to update it.
import { useState } from 'react';
import { View, Text, Button } from 'react-native';
function Counter() {
const [count, setCount] = useState(0); // initial value 0
return (
<View>
<Text>Count: {count}</Text>
<Button title="Add" onPress={() => setCount(count + 1)} />
</View>
);
}
const [count, setCount] = useState(0) reads as: “count is the value, setCount changes it, starting at 0”.
The golden rule: never mutate state directly
Always use the setter function. Changing the variable directly won’t re-render the UI.
count = count + 1; // ❌ wrong — UI won't update
setCount(count + 1); // ✅ correct
Updating based on the previous value
When the new value depends on the old one (especially in quick succession), pass a function to the setter to avoid bugs:
setCount(prev => prev + 1); // safest way to increment
State with objects and arrays
React replaces state, it doesn’t merge it, so create a new object/array instead of editing the old one:
const [user, setUser] = useState({ name: '', age: 0 });
setUser(prev => ({ ...prev, name: 'Anand' })); // copy + change one field
const [items, setItems] = useState([]);
setItems(prev => [...prev, newItem]); // add without mutating
A practical example: a text input
const [text, setText] = useState('');
<TextInput value={text} onChangeText={setText} placeholder="Type..." />
<Text>You typed: {text}</Text>
This “controlled input” pattern keeps your state and the field perfectly in sync.
Common mistakes
- Mutating state directly instead of using the setter.
- Editing an object/array in place instead of creating a new copy.
- Expecting state to update instantly — it applies on the next render, not the same line.
Summary:useStategives a component changeable data. Always update via the setter (use theprev =>form when based on the old value), and create new copies for objects/arrays rather than mutating them.