Nutzereingaben mit TextInput entgegennehmen
Eingaben mit TextInput
~9 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Jede App braucht früher oder später Texteingaben – eine Suche, ein Login-Formular, eine Adresse. In React Native übernimmt das die TextInput-Komponente.
Grundlagen: kontrollierte Eingabefelder
Anders als ein HTML-<input>, dessen Wert einfach im DOM lebt, ist ein TextInput in React Native (und React allgemein) üblicherweise ein "kontrolliertes" Feld: sein Wert kommt aus dem State, und jede Eingabe aktualisiert diesen State.
import { useState } from 'react';
import { TextInput, View, StyleSheet } from 'react-native';
function SuchFeld() {
const [suchtext, setSuchtext] = useState('');
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Produkt suchen..."
value={suchtext}
onChangeText={setSuchtext}
/>
</View>
);
}
const styles = StyleSheet.create({
container: { padding: 16 },
input: {
borderWidth: 1,
borderColor: '#d1d5db',
borderRadius: 8,
padding: 10,
fontSize: 16,
},
});| HTML/Web | React Native |
|---|---|
<input type="text" placeholder="..."> | <TextInput placeholder="..." /> |
input.addEventListener('input', e => ...) | onChangeText={{(text) => ...}} – bekommt direkt den neuen Textwert, kein Event-Objekt nötig |
input.value = suchtext (imperativ setzen) | value={{suchtext}} (deklarativ, aus dem State) |
<input type="password"> | <TextInput secureTextEntry /> |
<input type="email" inputmode="email"> | <TextInput keyboardType="email-address" /> – zeigt die passende Bildschirmtastatur |
CSS :focus-Styling | onFocus / onBlur Callback-Props + eigener State |
ProductListScreen.js um Live-Suche erweitern
Jetzt bauen wir das direkt in unseren echten screens/ProductListScreen.js aus Kapitel 10 ein. Ersetzen Sie den kompletten Inhalt der Datei durch diese erweiterte Version:
import { useState, useEffect } from 'react';
import {
View,
Text,
FlatList,
TextInput,
StyleSheet,
ActivityIndicator,
} from 'react-native';
import { fetchProducts } from '../api/magentoApi';
import ProductCard from '../components/ProductCard';
function ProductListScreen({ navigation }) {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
const [searchText, setSearchText] = useState('');
useEffect(() => {
async function loadProducts() {
try {
const items = await fetchProducts();
setProducts(items);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
}
loadProducts();
}, []);
if (loading) {
return <ActivityIndicator size="large" style={styles.loader} />;
}
const filteredProducts = products.filter((product) =>
product.name.toLowerCase().includes(searchText.toLowerCase())
);
return (
<View style={styles.container}>
<TextInput
style={styles.searchInput}
placeholder="Produkt suchen..."
value={searchText}
onChangeText={setSearchText}
/>
<FlatList
data={filteredProducts}
keyExtractor={(item) => item.sku}
renderItem={({ item }) => (
<ProductCard
name={item.name}
price={item.price}
imageUrl={item.imageUrl}
onPress={() =>
navigation.navigate('ProductDetail', { productSku: item.sku })
}
/>
)}
ListEmptyComponent={<Text style={styles.emptyText}>Keine Produkte gefunden.</Text>}
/>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, paddingTop: 16, paddingHorizontal: 16 },
loader: { flex: 1, justifyContent: 'center' },
searchInput: {
borderWidth: 1,
borderColor: '#d1d5db',
borderRadius: 8,
padding: 10,
fontSize: 16,
marginBottom: 12,
},
emptyText: { textAlign: 'center', marginTop: 24, color: '#6b7280' },
});
export default ProductListScreen;Neu ist der searchText-State, das TextInput-Feld über der Liste, und die Zeile const filteredProducts = products.filter(...). Bei jedem Tastenanschlag ändert sich searchText per setSearchText, die Komponente rendert neu, filteredProducts wird neu berechnet, und die FlatList zeigt automatisch nur noch passende Treffer – ganz ohne manuelles DOM-Filtern, wie Sie es im Web eventuell mit element.style.display = 'none' pro Zeile machen würden. Beachten Sie: die FlatList bekommt jetzt filteredProducts statt products als data.
Achtung: Bei großen Produktlisten (hunderte/tausende Einträge) sollte die Filterung idealerweise serverseitig über die Such-API laufen (bei Magento z. B. der /rest/V1/search-Endpunkt bzw. Elasticsearch), statt clientseitig durch das komplette Array zu iterieren – das lernen Sie in einem fortgeschrittenen Tutorial-Teil, sobald diese Serie um eine Debounce-Technik erweitert wird.