Managing State with useState (React Native Tutorial)
Managing State with useState
~10 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026
So far our components have been static – they always displayed the same values. Real apps need to remember and react to change: a cart counter, a search field, an on/off toggle. That's what useState is for.
Why a plain variable isn't enough
In HTML/JavaScript you'd use document.getElementById(...).textContent = ... to write directly into the DOM to change something on screen. React works differently: you never directly change what's displayed. Instead you change a state, and React automatically updates everything that depends on it – comparable to a spreadsheet cell that automatically recalculates when another cell it references changes.
useState() basics
import { useState } from 'react';
import { View, Text, Button } from 'react-native';
function CartCounter() {
const [count, setCount] = useState(0);
return (
<View>
<Text>In cart: {count}</Text>
<Button title="+ Add" onPress={() => setCount(count + 1)} />
</View>
);
}useState(0) creates a state value that starts at 0 and returns an array with two elements: the current value (count) and a function to change it (setCount). Important: you NEVER call count = 5 directly – always through the setter function. Every call to setCount(...) makes React redraw ("re-render") the component with the new value.
| HTML/Web | React Native |
|---|---|
let count = 0; + manual DOM update | const [count, setCount] = useState(0); – React updates the display automatically |
onclick="count++; render();" | onPress={() => setCount(count + 1)} |
Global state e.g. via localStorage or a custom event system | state stays local by default, inside the component that created it |
Extending ProductCard.js with favorite state
Now let's extend our real components/ProductCard.js from chapter 6 with a favorite heart button. Replace the entire content of the file with this version:
import { useState } from 'react';
import { View, Text, Image, StyleSheet, TouchableOpacity } from 'react-native';
function ProductCard({ name, price, imageUrl, onPress }) {
const [isFavorite, setIsFavorite] = useState(false);
return (
<TouchableOpacity style={styles.card} onPress={onPress}>
<Image source={{ uri: imageUrl }} style={styles.image} />
<View style={styles.info}>
<Text style={styles.name}>{name}</Text>
<Text style={styles.price}>${price.toFixed(2)}</Text>
</View>
<TouchableOpacity
style={styles.favoriteButton}
onPress={() => setIsFavorite(!isFavorite)}
>
<Text style={styles.favoriteIcon}>{isFavorite ? '♥' : '♡'}</Text>
</TouchableOpacity>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
card: {
flexDirection: 'row',
padding: 12,
marginBottom: 8,
backgroundColor: '#f9fafb',
borderRadius: 8,
alignItems: 'center',
},
image: { width: 60, height: 60, borderRadius: 4 },
info: { marginLeft: 12, flex: 1 },
name: { fontSize: 16, fontWeight: '600' },
price: { fontSize: 14, color: '#6b7280' },
favoriteButton: { padding: 8 },
favoriteIcon: { fontSize: 20, color: '#ef4444' },
});
export default ProductCard;What's new is the line const [isFavorite, setIsFavorite] = useState(false); plus the second, inner TouchableOpacity button with its own onPress. setIsFavorite(!isFavorite) flips the boolean value – from false to true and back. The expression {{isFavorite ? '♥' : '♡'}} is a "ternary operator", the compact shorthand for if/else inside an expression – very common in JSX, since you can't write a regular if statement there. App.js itself stays unchanged, since ProductCard fully manages its own favorite state.
Achtung: Every component instance has its OWN, independent state. Once you display several <ProductCard /> at once (starting in chapter 9), each has its own isFavorite state – tapping the heart on one card doesn't affect the others.