Appearance
Kapitel 8: React Hooks
Hooks sind Funktionen, die es Funktionskomponenten erlauben, State und andere React-Features zu verwenden.
8.1 Was sind Hooks?
🤔 Warum Hooks?
Vor Hooks (Klassenkomponenten):
- Komplexer Code
thisProbleme- Schwer zu wiederverwenden
Mit Hooks (Funktionskomponenten):
- Einfacher und kürzer
- Kein
this - Einfach Logik wiederzuverwenden
📝 Was können Hooks?
- State verwalten (
useState) - Seiteneffekte ausführen (
useEffect) - Auf DOM-Elemente zugreifen (
useRef) - Kontext verwenden (
useContext)
8.2 Wichtige Hooks
1️⃣ useState (State verwalten)
jsx
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Zähler: {count}</p>
<button onClick={() => setCount(count + 1)}>
Erhöhen
</button>
</div>
);
}Wichtig:
useState(initialValue)gibt ein Array zurück:[aktuellerWert, setterFunktion]setCountaktualisiert den State und löst ein Re-Rendering aus
2️⃣ useEffect (Seiteneffekte)
Was sind Seiteneffekte?
- Daten abrufen (API-Calls)
- DOM-Manipulation
- Timer setzen (
setTimeout,setInterval) - Event-Listener hinzufügen
Basis-Syntax
jsx
useEffect(() => {
// Code hier ausführen (nach jedem Rendering)
}, [dependencies]); // AbhängigkeitenSzenario 1: Nach jedem Rendering ausführen
jsx
useEffect(() => {
console.log('Komponente gerendert');
});Szenario 2: Nur einmal ausführen (wie componentDidMount)
jsx
useEffect(() => {
console.log('Nur einmal beim Mounten');
}, []); // Leeres Array = nur einmalSzenario 3: Bei State-Änderung ausführen
jsx
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`Count hat sich geändert: ${count}`);
}, [count]); // Nur wenn count sich ändertAufräumen von Seiteneffekten (Cleanup)
jsx
useEffect(() => {
const timer = setInterval(() => {
console.log('Tick...');
}, 1000);
// Cleanup-Funktion (wird vor dem nächsten Effekt oder Unmounten ausgeführt)
return () => {
clearInterval(timer);
};
}, []);Häufige Szenarien:
- Event-Listener entfernen
- Timer löschen
- API-Aufrufe abbrechen
3️⃣ useRef (DOM-Elemente & persistente Werte)
Zugriff auf DOM-Elemente
jsx
import { useRef } from 'react';
function App() {
const inputRef = useRef(null);
const handleClick = () => {
inputRef.current.focus(); // Fokus auf das Input-Feld setzen
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleClick}>Fokus setzen</button>
</div>
);
}Persistente Werte speichern
jsx
function Stopwatch() {
const [count, setCount] = useState(0);
const timerRef = useRef(null); // Speichert den Timer-ID
const start = () => {
timerRef.current = setInterval(() => {
setCount(prev => prev + 1);
}, 1000);
};
const stop = () => {
clearInterval(timerRef.current);
};
return (
<div>
<p>{count}</p>
<button onClick={start}>Start</button>
<button onClick={stop}>Stop</button>
</div>
);
}Wichtig: useRef löst kein Re-Rendering aus (im Gegensatz zu useState).
4️⃣ useContext (Kontext verwenden)
Problem: Props-Drilling vermeiden (Daten durch viele Ebenen weitergeben).
Schritt 1: Context erstellen
jsx
import { createContext, useContext } from 'react';
// Context erstellen
const UserContext = createContext();Schritt 2: Provider bereitstellen
jsx
function App() {
const user = { name: "Max", age: 25 };
return (
<UserContext.Provider value={user}>
<Header />
</UserContext.Provider>
);
}Schritt 3: Context in Kindkomponente verwenden
jsx
function Header() {
const user = useContext(UserContext);
return <h1>Willkommen, {user.name}!</h1>;
}Vorteile:
- Kein Props-Drilling
- Daten global verfügbar
8.3 Hooks-Regeln (WICHTIG!)
❌ Regel 1: Hooks nur auf oberster Ebene aufrufen
jsx
// ❌ Falsch: Hook in einer Bedingung
function App() {
if (true) {
const [count, setCount] = useState(0); // FEHLER!
}
}
// ✅ Richtig: Hook auf oberster Ebene
function App() {
const [count, setCount] = useState(0); // OK!
}❌ Regel 2: Hooks nur in React-Funktionen aufrufen
jsx
// ❌ Falsch: Hook in normaler Funktion
function myFunction() {
const [count, setCount] = useState(0); // FEHLER!
}
// ✅ Richtig: Hook in React-Komponente
function App() {
const [count, setCount] = useState(0); // OK!
}8.4 Benutzerdefinierte Hooks (Custom Hooks)
🎯 Was sind Custom Hooks?
Custom Hooks erlauben, Logik wiederzuverwenden.
Regel: Custom Hooks müssen mit use beginnen (z.B. useFetch, useLocalStorage).
📝 Beispiel: useFetch (Daten abrufen)
jsx
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(err => {
setError(err);
setLoading(false);
});
}, [url]);
return { data, loading, error };
}
// Verwendung
function App() {
const { data, loading, error } = useFetch('https://api.example.com/users');
if (loading) return <p>Lädt...</p>;
if (error) return <p>Fehler: {error.message}</p>;
return <div>{/* Daten anzeigen */}</div>;
}📝 Beispiel: useLocalStorage
jsx
import { useState } from 'react';
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
});
const updateValue = (newValue) => {
setValue(newValue);
localStorage.setItem(key, JSON.stringify(newValue));
};
return [value, updateValue];
}
// Verwendung
function App() {
const [name, setName] = useLocalStorage('name', 'Max');
return (
<div>
<p>{name}</p>
<button onClick={() => setName('Anna')}>Name ändern</button>
</div>
);
}📝 Zusammenfassung
In diesem Kapitel haben wir gelernt:
- ✅ Was Hooks sind und warum sie nützlich sind
- ✅
useState(State verwalten) - ✅
useEffect(Seiteneffekte ausführen) - ✅
useRef(DOM-Elemente & persistente Werte) - ✅
useContext(Kontext verwenden) - ✅ Hooks-Regeln (nur auf oberster Ebene, nur in React-Funktionen)
- ✅ Benutzerdefinierte Hooks erstellen
🎯 Nächste Schritte
Im nächsten Kapitel werden wir lernen:
- Komponenten-Kommunikation (Props, Callbacks, Context)
- Daten zwischen Komponenten austauschen
Bereit für Kommunikation? → Kapitel 9: Komponenten-Kommunikation
