Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

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/WebReact 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-StylingonFocus / 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:

screens/ProductListScreen.js
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.