Svenska

Frigör kraften i återanvändbar logik i dina React-applikationer med anpassade krokar. Lär dig hur du skapar och använder anpassade krokar för renare och mer underhållbar kod.

Anpassade Krokar: Återanvändbara Logikmönster i React

React Hooks revolutionerade sättet vi skriver React-komponenter på genom att introducera tillstånd och livscykelfunktioner i funktionella komponenter. Bland de många fördelarna de erbjuder, utmärker sig anpassade krokar som en kraftfull mekanism för att extrahera och återanvända logik över flera komponenter. Detta blogginlägg kommer att djupdyka i världen av anpassade krokar, och utforska deras fördelar, skapande och användning med praktiska exempel.

Vad är Anpassade Krokar?

I grund och botten är en anpassad krok en JavaScript-funktion som börjar med ordet "use" och kan anropa andra krokar. De låter dig extrahera komponentlogik till återanvändbara funktioner. Detta är ett kraftfullt sätt att dela tillståndsbaserad logik, sidoeffekter eller andra komplexa beteenden mellan komponenter utan att behöva använda render props, högre ordningens komponenter eller andra komplexa mönster.

Nyckelegenskaper för Anpassade Krokar:

Fördelar med att Använda Anpassade Krokar

Anpassade krokar erbjuder flera betydande fördelar i React-utveckling:

Skapa Din Första Anpassade Krok

Låt oss illustrera skapandet av en anpassad krok med ett praktiskt exempel: en krok som spårar fönsterstorleken.

Exempel: useWindowSize

Denna krok kommer att returnera den aktuella bredden och höjden på webbläsarfönstret. Den kommer också att uppdatera dessa värden när fönstret storleksändras.

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);

    // Ta bort händelselyssnare vid städning
    return () => window.removeEventListener('resize', handleResize);
  }, []); // Tom array säkerställer att effekten endast körs vid montering

  return windowSize;
}

export default useWindowSize;

Förklaring:

  1. Importera Nödvändiga Krokar: Vi importerar useState och useEffect från React.
  2. Definiera Kroken: Vi skapar en funktion med namnet useWindowSize, enligt namnkonventionen.
  3. Initiera Tillstånd: Vi använder useState för att initiera windowSize-tillståndet med fönstrets initiala bredd och höjd.
  4. Sätt Upp Händelselyssnare: Vi använder useEffect för att lägga till en 'resize'-händelselyssnare på fönstret. När fönstret storleksändras uppdaterar handleResize-funktionen windowSize-tillståndet.
  5. Städning: Vi returnerar en städningsfunktion från useEffect för att ta bort händelselyssnaren när komponenten avmonteras. Detta förhindrar minnesläckor.
  6. Returnera Värden: Kroken returnerar windowSize-objektet, som innehåller fönstrets aktuella bredd och höjd.

Använda den Anpassade Kroken i en Komponent

Nu när vi har skapat vår anpassade krok, låt oss se hur man använder den i en React-komponent.

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

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

  return (
    

Window width: {width}px

Window height: {height}px

); } export default MyComponent;

Förklaring:

  1. Importera Kroken: Vi importerar den anpassade kroken useWindowSize.
  2. Anropa Kroken: Vi anropar useWindowSize-kroken inuti komponenten.
  3. Åtkomst till Värden: Vi destrukurerar det returnerade objektet för att få width- och height-värdena.
  4. Rendera Värden: Vi renderar bredd- och höjdvärdena i komponentens UI.

Alla komponenter som använder useWindowSize kommer automatiskt att uppdateras när fönsterstorleken ändras.

Mer Komplexa Exempel

Låt oss utforska några mer avancerade användningsfall för anpassade krokar.

Exempel: useLocalStorage

Denna krok låter dig enkelt lagra och hämta data från local storage.

import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
  // Tillstånd för att lagra vårt värde
  // Skicka initialvärde till useState så att logiken bara körs en gång
  const [storedValue, setStoredValue] = useState(() => {
    try {
      // Hämta från local storage med nyckel
      const item = window.localStorage.getItem(key);
      // Parsa lagrad json eller returnera initialValue om ingen finns
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      // Om fel, returnera också initialValue
      console.log(error);
      return initialValue;
    }
  });

  // Returnera en inlindad version av useStates setter-funktion som ...
  // ... sparar det nya värdet till localStorage.
  const setValue = (value) => {
    try {
      // Tillåt att värdet är en funktion så att vi har samma API som useState
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      // Spara till local storage
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
      // Spara tillstånd
      setStoredValue(valueToStore);
    } catch (error) {
      // En mer avancerad implementation skulle hantera fel fallet
      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;

Användning:

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

function MyComponent() {
  const [name, setName] = useLocalStorage('name', 'Guest');

  return (
    

Hello, {name}!

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

Exempel: useFetch

Denna krok kapslar in logiken för att hämta data från ett 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;

Användning:

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

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

  if (loading) return 

Loading...

; if (error) return

Error: {error.message}

; return (

Title: {data.title}

Completed: {data.completed ? 'Yes' : 'No'}

); } export default MyComponent;

Bästa Praxis för Anpassade Krokar

För att säkerställa att dina anpassade krokar är effektiva och underhållbara, följ dessa bästa praxis:

Vanliga Fallgropar att Undvika

Avancerade Mönster

Komponera Anpassade Krokar

Anpassade krokar kan komponeras tillsammans för att skapa mer komplex logik. Till exempel kan du kombinera en useLocalStorage-krok med en useFetch-krok för att automatiskt spara hämtad data till local storage.

Dela Logik Mellan Krokar

Om flera anpassade krokar delar gemensam logik kan du extrahera den logiken till en separat hjälpfunktion och återanvända den i båda krokarna.

Använda Context med Anpassade Krokar

Anpassade krokar kan användas tillsammans med React Context för att komma åt och uppdatera globalt tillstånd. Detta låter dig skapa återanvändbara komponenter som är medvetna om och kan interagera med applikationens globala tillstånd.

Verkliga Exempel

Här är några exempel på hur anpassade krokar kan användas i verkliga applikationer:

Exempel : useGeolocation-krok för tvärkulturella applikationer som karttjänster eller leveranstjänster

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 is not supported by this 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;

Slutsats

Anpassade krokar är ett kraftfullt verktyg för att skriva renare, mer återanvändbar och mer underhållbar React-kod. Genom att kapsla in komplex logik i anpassade krokar kan du förenkla dina komponenter, minska kodduplicering och förbättra den övergripande strukturen i dina applikationer. Omfamna anpassade krokar och frigör deras potential att bygga mer robusta och skalbara React-applikationer.

Börja med att identifiera områden i din befintliga kodbas där logik upprepas över flera komponenter. Refaktorera sedan den logiken till anpassade krokar. Med tiden kommer du att bygga ett bibliotek av återanvändbara krokar som kommer att påskynda din utvecklingsprocess och förbättra kvaliteten på din kod.

Kom ihåg att följa bästa praxis, undvika vanliga fallgropar och utforska avancerade mönster för att få ut det mesta av anpassade krokar. Med övning och erfarenhet kommer du att bli en mästare på anpassade krokar och en mer effektiv React-utvecklare.