En jämförelse av datahämtningskrokar i React

React-krokar är ett kraftfullt sätt att hantera biverkningar i React-komponenter. Tre av de vanligaste krokarna för att hantera biverkningar är useEffect, useLayoutEffect och useEffectEvent. Varje krok har sitt unika användningsområde, så det är viktigt att välja rätt för jobbet.

UseEffect Hook

UseEffect-kroken är en grundläggande krok i React som låter dig utföra biverkningar som DOM-manipulation, asynkrona operationer och datahämtning i funktionella komponenter. Denna krok är en funktion som tar två argument, effektfunktionen och beroendematrisen.

Effektfunktionen innehåller koden som utför bieffekten, och beroendematrisen bestämmer när effektfunktionen körs. Om beroendematrisen är tom, körs effektfunktionen endast en gång vid den initiala renderingen av komponenten. Annars körs effektfunktionen när något av värdena i beroendematrisen ändras.

Här är ett exempel på hur man använder useEffect-kroken för att hämta data:

 import React from "react";

function App() {
  const [data, setData] = React.useState([]);

  React.useEffect(() => {
    fetch("<https://jsonplaceholder.typicode.com/posts>")
      .then((response) => response.json())
      .then((data) => setData(data));
  }, []);

  return (
    <div className="app">
      {data.map((item) => (
        <div key={item.id}>{item.title}</div>
      ))}
    </div>
  );
}

export default App;

Den här koden visar en appkomponent som hämtar data från ett externt API med hjälp av useEffect-kroken. Effektfunktionen för useEffect hämtar exempeldata från JSONPlaceholder API. Den analyserar sedan JSON-svaret och ställer in den hämtade datan till datatillståndet.

Med datatillståndet återger appkomponenten titelegenskapen för varje objekt i tillståndet.

Egenskaper för användningenEffect Hook

  • Asynkronvänlig: Den stöder asynkrona operationer inbyggt, vilket gör det bekvämt för datahämtning.
  • Körs efter rendering: useEffect-kroken exekverar sina effekter efter att applikationen har renderat komponenten, och säkerställer att kroken inte blockerar användargränssnittet.
  • Rengöring: Det ger ett integrerat sätt att utföra rensning genom att returnera en funktion. Detta kan vara särskilt användbart när du arbetar med lyssnare eller prenumerationer.

UseLayoutEffect Hook

UseLayoutEffect-kroken liknar useEffect-kroken men körs synkront efter alla DOM-mutationer. Detta innebär att den körs innan webbläsaren kan måla skärmen, vilket gör den lämplig för uppgifter som kräver exakt kontroll över DOM-layouten och stilar, som att mäta storleken på ett element, ändra storlek på ett element eller animera dess position.

Nedan är ett exempel på hur man använder useLayoutEffect-kroken för att ändra bredden på ett knappelement:

 import React from "react";

function App() {
  const button = React.useRef();

  React.useLayoutEffect(() => {
    const { width } = button.current.getBoundingClientRect();

    button.current.style.width = `${width + 12}px`;
  }, []);

  return (
    <div className="app">
      <button ref={button}>Click Me</button>
    </div>
  );
}

export default App;

Kodblocket ovan ökar bredden på knappelementet med 12 pixlar med hjälp av useLayoutEffect-kroken. Detta säkerställer att knappens bredd ökar innan knappen visas på skärmen.

Egenskaper för useLayoutEffect Hook

  • Synkron: Den körs synkront, vilket potentiellt blockerar användargränssnittet om operationen i den är tung.
  • DOM läs/skriv: Den är bäst lämpad för att läsa och skriva direkt till DOM, speciellt om du behöver ändringarna innan webbläsaren målas om.

UseEffectEvent Hook

UseEffectEvent-kroken är en React-krok som löser beroendeproblemen för useEffect-kroken. Om du är bekant med useEffect vet du att dess beroendematris kan vara knepig. Ibland måste du lägga in fler värden i beroendematrisen som är absolut nödvändiga.

Till exempel:

 import React from "react";

function App() {
  const connect = (url) => {
    
  };

  const logConnection = (message, loginOptions) => {
    
  };

  const onConnected = (url, loginOptions) => {
    logConnection(`Connected to ${url}`, loginOptions);
  };

  React.useEffect(() => {
    const device = connect(url);
    device.onConnected(() => {
      onConnected(url);
    });

    return () => {
      device.disconnect();
    };
  }, [url, onConnected]);

  return <div></div>;
}

export default App;

Den här koden visar appkomponenten som hanterar en anslutning till en extern tjänst. Anslutningsfunktionen ansluter till en angiven URL, medan logConnection-funktionen loggar anslutningsdetaljerna. Slutligen anropar funktionen onConnected funktionen logConnection för att logga ett lyckat anslutningsmeddelande när enheten ansluter.

useEffect-kroken anropar connect-funktionen och ställer sedan in en onConnected-återuppringningsfunktion som körs när enheten utlöser onConnected-händelsen. Denna återuppringning loggar ett anslutningsmeddelande. Den returnerar en rensningsfunktion som aktiveras när komponenten avmonteras. Denna rengöringsfunktion ansvarar för att koppla bort enheten.

Beroendematrisen har url-variabeln och onConnected-funktionen. App-komponenten kommer att skapa onConnected-funktionen vid varje rendering. Detta kommer att göra att useEffect-funktionen körs i en loop, som kommer att fortsätta att återrendera appkomponenten.

Det finns flera sätt att lösa problemet med useEffect-slingan. Ändå är det mest effektiva sättet att göra det utan att lägga till fler onödiga värden till din beroendematris med useEffectEvent-kroken.

 import React from "react";

function App() {
  const connect = (url) => {
    
  };

  const logConnection = (message, loginOptions) => {
    
  };

  const onConnected = React.useEffectEvent((url, loginOptions) => {
    logConnection(`Connected to ${url}`, loginOptions);
  });

  React.useEffect(() => {
    const device = connect(url);
    device.onConnected(() => {
      onConnected(url);
    });

    return () => {
      device.disconnect();
    };
  }, [url]);

  return <div></div>;
}
export default App;

Genom att slå in onConnected-funktionen med useEffectEvent-kroken kan useEffectEvent-kroken alltid läsa de senaste värdena för meddelandet och loginOptions-parametrarna innan det skickas till useEffect-kroken. Detta innebär att useEffect inte behöver förlita sig på onConnected-funktionen eller de värden som skickas till den.

useEffectEvent-kroken är användbar när du vill att din useEffect ska bero på ett specifikt värde, även om effekten utlöser en händelse som kräver andra värden som du föredrar att inte använda som beroenden i useEffect.

Egenskaper för användningenEffectEvent Hook

  • Det är bäst lämpat för händelsedrivna biverkningar.
  • UseEffectEvent-kroken fungerar inte med händelsehanterare som onClick, onChange, etc.

UseEffectEvent-kroken är fortfarande experimentell och inte tillgänglig i React version 18-krokar.

När ska man använda vilken krok?

Var och en av ovanstående datahämtningskrokar är lämpliga för olika situationer:

  • Hämta data: UseEffect är ett utmärkt val.
  • Direkta DOM-manipulationer: Om du behöver göra synkrona ändringar av DOM innan en ommålning, välj useLayoutEffect.
  • Lättviktsoperationer: För operationer som inte riskerar att blockera användargränssnittet kan du fritt använda useEffect.
  • Händelsedrivna biverkningar: Använd useEffectEvent-kroken för att avsluta händelserna och useEffect-kroken för att köra biverkningarna.

Hantera biverkningar effektivt

React-hakarna öppnar upp en värld av möjligheter, och att förstå skillnaden mellan useEffect, useLayoutEffect och useEffectEvent-hakarna kan avsevärt påverka hur du hanterar biverkningar och DOM-manipulation. Det är viktigt att överväga dessa krokars specifika krav och konsekvenser för att göra användarvänliga applikationer.