Functional Component — ist eine Möglichkeit, React-Komponenten mit gewöhnlichen JavaScript-Funktionen zu erstellen, die nach der Veröffentlichung von React 16.8 und der Einführung von Hooks zum Standard wurde. Funktionale Komponenten akzeptieren Props und geben React-Elemente zurück, ohne eine Vererbung von React.Component zu erfordern. Laut React, 2024 werden 97% der neuen Komponenten im React-Ökosystem als Funktionen geschrieben.
Wichtige Erkenntnisse
Functional Component ist eine React-Komponente, die als Funktion definiert ist, die ein Props-Objekt akzeptiert und ein React-Element zurückgibt. Vor React 16.8 wurden solche Komponenten als zustandslos bezeichnet, da sie keinen internen Zustand verwalten konnten.
Mit der Einführung von Hooks in React 16.8 (Februar 2019) erhielten funktionale Komponenten Zugriff auf State (useState), Seiteneffekte (useEffect), Kontext (useContext) und Refs (useRef). Der Begriff „zustandslos“ ist veraltet — moderne funktionale Komponenten verwalten den Zustand vollständig.
React empfiehlt offiziell funktionale Komponenten als primäre Methode zum Erstellen von Komponenten. Die gesamte Dokumentation auf react.dev, Beispiele, Tutorials und neue APIs (Server Components, Actions) basieren auf dem funktionalen Ansatz. Klassenkomponenten wurden nicht entfernt, aber neue React-Funktionen sind nur über Hooks verfügbar.
Die einfachste Funktionskomponente ist eine Funktion, die JSX zurückgibt. Sie akzeptiert Props als Argument, benötigt keinen Konstruktor, super-Aufruf oder this-Bindung. Props sind direkt über das Funktionsargument zugänglich — kein this.props erforderlich.
// Functional component without state
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
// Arrow function (common variant)
const Greeting = ({ name }) => (
<h1>Hello, {name}!</h1>
);
Um Zustand hinzuzufügen, verwenden Sie useState. Der Hook gibt ein Tupel von zwei Werten zurück: den aktuellen Zustand und eine Setter-Funktion. Im Gegensatz zum klassenbasierten this.setState ersetzt useState den Wert vollständig, anstatt ihn mit dem vorherigen zu verschmelzen.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
Hooks sind die Grundlage von modernem React. Jeder Hook löst eine bestimmte Aufgabe: useState — Zustand, useEffect — Seiteneffekte, useContext — Kontextzugriff, useRef — DOM-Elementreferenzen, useCallback und useMemo — Memoisation.
useEffect ersetzt componentDidMount, componentDidUpdate und componentWillUnmount gleichzeitig. Das erste Argument ist ein Callback mit dem Effekt, das zweite ist ein Abhängigkeitsarray. Wenn das Array leer ist, wird der Effekt einmal nach dem Mounten ausgeführt. Wenn Abhängigkeiten angegeben sind, wird er bei jeder Änderung einer von ihnen ausgeführt.
import React, { useState, useEffect } from 'react';
function UserData({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
let cancelled = false;
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => {
if (!cancelled) setUser(data);
});
// Cleanup - analog of componentWillUnmount
return () => { cancelled = true; };
}, [userId]); // Dependency
return <div>{user?.name}</div>;
}
Der Hauptvorteil funktionaler Komponenten ist die Wiederverwendung von Logik durch benutzerdefinierte Hooks. Während in einer Klassenkomponente die Logik zwischen componentDidMount und componentDidUpdate dupliziert wurde, wird sie in einer Funktionskomponente in eine separate Funktion mit dem Präfix use extrahiert. Benutzerdefinierte Hooks sind die primäre Alternative zu HOC und Render Props.
React empfiehlt Komposition statt Vererbung zur Wiederverwendung von Code zwischen Komponenten. Funktionale Komponenten sind ideal für Komposition: Eine Komponente kann mehrere andere enthalten und ihnen Props und Children übergeben.
Das Children-Muster — wenn eine Komponente Kindelemente über die Prop Children empfängt — wird natürlich implementiert: function Layout({ children }). Das Analogon zu Vue-Slots wird durch benannte Komponenten-Props implementiert: function Page({ header, sidebar, content }).
Vererbung wird in React kaum verwendet. Selbst Klassenkomponenten, die technisch extends unterstützen, bilden selten Hierarchien, die tiefer als eine Ebene sind. Funktionale Komponenten mit Komposition decken die Anforderungen an die Code-Wiederverwendung ohne Vererbung vollständig ab.
Funktionale Komponenten verfügen über eingebaute Optimierungsmechanismen. React.memo — das Äquivalent zu PureComponent für Funktionen: verhindert erneutes Rendern, wenn sich Props nicht geändert haben (oberflächlicher Vergleich). useMemo speichert Berechnungsergebnisse zwischen Renderings zwischen.
import React, { useMemo } from 'react';
// React.memo - memoize component
const ExpensiveList = React.memo(({ items }) => {
return <ul>
{items.map(item =>
<li key={item.id}>{item.name}</li>
)}
</ul>;
});
// useMemo - caching result
function Dashboard({ transactions }) {
const summary = useMemo(() => {
return transactions.reduce((acc, t) => acc + t.amount, 0);
}, [transactions]);
return <p>Total: {summary}</p>;
}
useCallback memoisiert Callback-Funktionen, damit sie nicht bei jedem Rendern neu erstellt werden. Dies ist entscheidend beim Übergeben von Funktionen an Kindkomponenten, die in React.memo eingewickelt sind: Ohne useCallback wird die Kindkomponente jedes Mal neu gerendert, weil sich die Funktionsreferenz ändert.
Der Unterschied zwischen den Ansätzen geht über die Syntax hinaus. Funktionale Komponenten sind Closures: Zustand und Effekte sind an ein bestimmtes Rendering gebunden. Klassenkomponenten verwenden this: Der Zustand wird immer von this.state bezogen, der zum Zeitpunkt der Ausführung eines asynchronen Callbacks veraltet sein kann.
| Aspekt | Funktional | Klasse |
|---|---|---|
| Zustand | useState (isoliert) | this.state + this.setState |
| Effekte | useEffect mit Abhängigkeiten | componentDidMount + componentDidUpdate |
| Kontext | useContext | Context.Consumer oder static contextType |
| Optimierung | React.memo + useMemo | PureComponent + shouldComponentUpdate |
| Logik-Wiederverwendung | Benutzerdefinierte Hooks | HOC / Render Props |
| this | Keines | Bind im Konstruktor |
Funktionale Komponenten bieten einen linearen Ausführungsfluss. In einer Klassenkomponente ist verwandte Logik oft über mehrere Lebenszyklusmethoden verstreut. Zum Beispiel wird ein WebSocket-Abonnement in componentDidMount eingerichtet und in componentWillUnmount entfernt. In einer Funktionskomponente befinden sich beide Operationen in einem einzigen useEffect mit einer Bereinigungsfunktion als Rückgabe.
TypeScript funktioniert natürlicher mit funktionalen Komponenten als mit Klassen. Props-Typisierung — ein Interface für das Funktionsargument. Der Rückgabetyp ist JSX.Element oder ReactNode. useState leitet den Typ automatisch aus dem Anfangswert ab.
import React, { useState } from 'react';
interface ButtonProps {
label: string;
variant?: 'primary' | 'secondary';
onClick: () => void;
}
const Button: React.FC<ButtonProps> =
({ label, variant = 'primary', onClick }) => (
<button
className={`btn btn-${variant}`}
onClick={onClick}
>
{label}
</button>
);
Modernes TypeScript erlaubt die Typisierung von useReducer mit diskriminierten Union-Typen, Generics in benutzerdefinierten Hooks und strenge Children-Validierung durch React.PropsWithChildren. Funktionale Komponenten mit TypeScript bieten vollständige Typsicherheit ohne zusätzliche Abstraktionen.
Häufig gestellte Fragen
Funktionale Komponenten sind einfacher: kein Konstruktor, Bind, this oder verstreute Lebenszyklusmethoden. Hooks ermöglichen das Gruppieren verwandter Logik. React investiert Ressourcen in die Entwicklung von Hooks, nicht von Klassen. Server Components und neue Funktionen sind nur in Funktionen verfügbar.
Ja, durch useEffect mit einem Timer darin und einer Bereinigungsfunktion für clearInterval. Beachten Sie die Closure: Wenn Sie einen Zähler ticken lassen, verwenden Sie die funktionale Form von setState: setCount(c => c + 1), um nicht vom alten Wert in der Closure abhängig zu sein.
Verwenden Sie useRef, um den vorherigen Wert zu speichern. Aktualisieren Sie den Ref in useEffect nach jedem Rendern. Ein benutzerdefinierter Hook usePrevious hilft beim sauberen Vergleich: const prev = usePrevious(value);
React.memo ist ein HOC zum Memoisieren einer gesamten Komponente: verhindert erneutes Rendern, wenn sich Props nicht geändert haben. useMemo ist ein Hook zum Memoisieren eines bestimmten Werts innerhalb einer Komponente: speichert das Ergebnis einer Funktion zwischen Renderings basierend auf einem Abhängigkeitsarray zwischen.
Der einfachste Weg ist useState mit Initialisierung von Props + useEffect mit einer Abhängigkeit von Props zur Synchronisation. Für seltene Fälle empfiehlt React die Verwendung eines Keys, um die Neuerstellung der Komponente bei Änderung der Eingabedaten zu erzwingen.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch