Skip to content

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
  • this Probleme
  • 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]
  • setCount aktualisiert 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ängigkeiten

Szenario 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 einmal

Szenario 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 ändert

Aufrä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

Frei für alle Anfänger