Dansk

Frigør potentialet i genanvendelig logik i dine React-applikationer med custom hooks. Lær at skabe og udnytte custom hooks for renere og mere vedligeholdelig kode.

Custom Hooks: Genanvendelige Logikmønstre i React

React Hooks revolutionerede den måde, vi skriver React-komponenter på, ved at introducere state- og livscyklusfunktioner til funktionelle komponenter. Blandt de mange fordele, de tilbyder, skiller custom hooks sig ud som en kraftfuld mekanisme til at udtrække og genbruge logik på tværs af flere komponenter. Dette blogindlæg vil dykke dybt ned i verdenen af custom hooks og udforske deres fordele, oprettelse og brug med praktiske eksempler.

Hvad er Custom Hooks?

Grundlæggende er en custom hook en JavaScript-funktion, der starter med ordet "use" og kan kalde andre hooks. De giver dig mulighed for at udtrække komponentlogik til genanvendelige funktioner. Dette er en effektiv måde at dele stateful logik, sideeffekter eller anden kompleks adfærd mellem komponenter uden at ty til render props, higher-order components eller andre komplekse mønstre.

Nøglekarakteristika for Custom Hooks:

Fordele ved at bruge Custom Hooks

Custom hooks tilbyder flere betydelige fordele i React-udvikling:

Oprettelse af din første Custom Hook

Lad os illustrere oprettelsen af en custom hook med et praktisk eksempel: en hook, der sporer vinduesstørrelsen.

Eksempel: useWindowSize

Denne hook returnerer den aktuelle bredde og højde på browservinduet. Den vil også opdatere disse værdier, når vinduet ændres i størrelse.

import { useState, useEffect } from 'react';

function useWindowSize() {
  const [windowSize, setWindowSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight,
  });

  useEffect(() => {
    function handleResize() {
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    }

    window.addEventListener('resize', handleResize);

    // Remove event listener on cleanup
    return () => window.removeEventListener('resize', handleResize);
  }, []); // Empty array ensures that effect is only run on mount

  return windowSize;
}

export default useWindowSize;

Forklaring:

  1. Importer nødvendige Hooks: Vi importerer useState og useEffect fra React.
  2. Definer hooken: Vi opretter en funktion ved navn useWindowSize, som overholder navnekonventionen.
  3. Initialiser State: Vi bruger useState til at initialisere windowSize-state med den indledende bredde og højde på vinduet.
  4. Opsæt Event Listener: Vi bruger useEffect til at tilføje en 'resize' event listener til vinduet. Når vinduet ændres i størrelse, opdaterer handleResize-funktionen windowSize-state.
  5. Oprydning: Vi returnerer en oprydningsfunktion fra useEffect for at fjerne event listeneren, når komponenten afmonteres. Dette forhindrer hukommelseslækager.
  6. Returner værdier: Hooken returnerer windowSize-objektet, som indeholder den aktuelle bredde og højde på vinduet.

Brug af en Custom Hook i en Komponent

Nu hvor vi har oprettet vores custom hook, lad os se, hvordan man bruger den i en React-komponent.

import React from 'react';
import useWindowSize from './useWindowSize';

function MyComponent() {
  const { width, height } = useWindowSize();

  return (
    

Vinduesbredde: {width}px

Vindueshøjde: {height}px

); } export default MyComponent;

Forklaring:

  1. Importer hooken: Vi importerer useWindowSize custom hooken.
  2. Kald hooken: Vi kalder useWindowSize-hooken inde i komponenten.
  3. Få adgang til værdier: Vi destrukturerer det returnerede objekt for at få width- og height-værdierne.
  4. Render værdier: Vi renderer bredde- og højdeværdierne i komponentens UI.

Enhver komponent, der bruger useWindowSize, vil automatisk blive opdateret, når vinduesstørrelsen ændres.

Mere komplekse eksempler

Lad os udforske nogle mere avancerede anvendelsesmuligheder for custom hooks.

Eksempel: useLocalStorage

Denne hook giver dig mulighed for nemt at gemme og hente data fra local storage.

import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
  // State to store our value
  // Pass initial value to useState so logic is only executed once
  const [storedValue, setStoredValue] = useState(() => {
    try {
      // Get from local storage by key
      const item = window.localStorage.getItem(key);
      // Parse stored json or if none return initialValue
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      // If error also return initialValue
      console.log(error);
      return initialValue;
    }
  });

  // Return a wrapped version of useState's setter function that ...
  // ... persists the new value to localStorage.
  const setValue = (value) => {
    try {
      // Allow value to be a function so we have same API as useState
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      // Save to local storage
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
      // Save state
      setStoredValue(valueToStore);
    } catch (error) {
      // A more advanced implementation would handle the error case
      console.log(error);
    }
  };

  useEffect(() => {
    try {
      const item = window.localStorage.getItem(key);
      setStoredValue(item ? JSON.parse(item) : initialValue);
    } catch (error) {
      console.log(error);
    }
  }, [key, initialValue]);

  return [storedValue, setValue];
}

export default useLocalStorage;

Anvendelse:

import React from 'react';
import useLocalStorage from './useLocalStorage';

function MyComponent() {
  const [name, setName] = useLocalStorage('name', 'Gæst');

  return (
    

Hej, {name}!

setName(e.target.value)} />
); } export default MyComponent;

Eksempel: useFetch

Denne hook indkapsler logikken for at hente data fra et API.

import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }
        const json = await response.json();
        setData(json);
        setLoading(false);
      } catch (error) {
        setError(error);
        setLoading(false);
      }
    }

    fetchData();
  }, [url]);

  return { data, loading, error };
}

export default useFetch;

Anvendelse:

import React from 'react';
import useFetch from './useFetch';

function MyComponent() {
  const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/todos/1');

  if (loading) return 

Indlæser...

; if (error) return

Fejl: {error.message}

; return (

Titel: {data.title}

Fuldført: {data.completed ? 'Ja' : 'Nej'}

); } export default MyComponent;

Bedste Praksis for Custom Hooks

For at sikre, at dine custom hooks er effektive og vedligeholdelige, skal du følge disse bedste praksisser:

Almindelige faldgruber at undgå

Avancerede Mønstre

Sammensætning af Custom Hooks

Custom hooks kan sammensættes for at skabe mere kompleks logik. For eksempel kan du kombinere en useLocalStorage-hook med en useFetch-hook for automatisk at gemme hentede data i local storage.

Deling af logik mellem hooks

Hvis flere custom hooks deler fælles logik, kan du udtrække den logik til en separat hjælpefunktion og genbruge den i begge hooks.

Brug af Context med Custom Hooks

Custom hooks kan bruges i forbindelse med React Context for at få adgang til og opdatere global state. Dette giver dig mulighed for at skabe genanvendelige komponenter, der er bevidste om og kan interagere med applikationens globale state.

Eksempler fra den virkelige verden

Her er nogle eksempler på, hvordan custom hooks kan bruges i virkelige applikationer:

Eksempel: useGeolocation hook til tværkulturelle applikationer som kortlægning eller leveringstjenester

import { useState, useEffect } from 'react';

function useGeolocation() {
  const [location, setLocation] = useState({
    latitude: null,
    longitude: null,
    error: null,
  });

  useEffect(() => {
    if (!navigator.geolocation) {
      setLocation({
        latitude: null,
        longitude: null,
        error: 'Geolocation understøttes ikke af denne browser.',
      });
      return;
    }

    const watchId = navigator.geolocation.watchPosition(
      (position) => {
        setLocation({
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
          error: null,
        });
      },
      (error) => {
        setLocation({
          latitude: null,
          longitude: null,
          error: error.message,
        });
      }
    );

    return () => navigator.geolocation.clearWatch(watchId);
  }, []);

  return location;
}

export default useGeolocation;

Konklusion

Custom hooks er et kraftfuldt værktøj til at skrive renere, mere genanvendelig og mere vedligeholdelig React-kode. Ved at indkapsle kompleks logik i custom hooks kan du forenkle dine komponenter, reducere kodeduplikering og forbedre den overordnede struktur af dine applikationer. Omfavn custom hooks og frigør deres potentiale til at bygge mere robuste og skalerbare React-applikationer.

Start med at identificere områder i din eksisterende kodebase, hvor logik gentages på tværs af flere komponenter. Refaktorér derefter den logik til custom hooks. Over tid vil du opbygge et bibliotek af genanvendelige hooks, der vil fremskynde din udviklingsproces og forbedre kvaliteten af din kode.

Husk at følge bedste praksis, undgå almindelige faldgruber og udforske avancerede mønstre for at få mest muligt ud af custom hooks. Med øvelse og erfaring vil du blive en mester i custom hooks og en mere effektiv React-udvikler.