window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', versjon: 2, } ;(function () { var w = vindu if (w.LeadBooster) { console.warn('LeadBooster finnes allerede') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() En dypere titt på de mest populære React-krokene - The Codest
The Codest
  • Om oss
  • Tjenester
    • Programvareutvikling
      • Frontend-utvikling
      • Backend-utvikling
    • Staff Augmentation
      • Frontend-utviklere
      • Backend-utviklere
      • Dataingeniører
      • Ingeniører i skyen
      • QA-ingeniører
      • Annet
    • Det rådgivende
      • Revisjon og rådgivning
  • Industrier
    • Fintech og bankvirksomhet
    • E-commerce
    • Adtech
    • Helseteknologi
    • Produksjon
    • Logistikk
    • Bilindustrien
    • IOT
  • Verdi for
    • ADMINISTRERENDE DIREKTØR
    • CTO
    • Leveransesjef
  • Vårt team
  • Casestudier
  • Vet hvordan
    • Blogg
    • Møter
    • Webinarer
    • Ressurser
Karriere Ta kontakt med oss
  • Om oss
  • Tjenester
    • Programvareutvikling
      • Frontend-utvikling
      • Backend-utvikling
    • Staff Augmentation
      • Frontend-utviklere
      • Backend-utviklere
      • Dataingeniører
      • Ingeniører i skyen
      • QA-ingeniører
      • Annet
    • Det rådgivende
      • Revisjon og rådgivning
  • Verdi for
    • ADMINISTRERENDE DIREKTØR
    • CTO
    • Leveransesjef
  • Vårt team
  • Casestudier
  • Vet hvordan
    • Blogg
    • Møter
    • Webinarer
    • Ressurser
Karriere Ta kontakt med oss
Pil tilbake GÅ TILBAKE
2021-12-07
Programvareutvikling

En dypere titt på de mest populære React-krokene

The Codest

Pawel Rybczynski

Software Engineer

I løpet av mange intervjuer har jeg lagt merke til at selv erfarne programmerere har problemer med å skille mellom Hooks, for ikke å snakke om de mer avanserte funksjonene. Derfor vil jeg i denne artikkelen prøve å forklare hvordan Hooks bør brukes.

Det viktigste du trenger å huske om Hooks:

  • de kan bare brukes i funksjonskomponenter - klassekomponenter har egen livssyklusimplementering;
  • de begynner alltid med bruk;
  • kan du bruke så mange Hooks du vil, men du må huske at bruken av dem har innvirkning på den generelle ytelsen;
  • de må utføres i samme rekkefølge ved hver rendering ... men hvorfor? La oss ta en titt på et eksempel:
import { useState,useEffect } fra "react";

export default function FunctionComponent() {
const [value, setValue] = useState(1);
const [doubleValue, setDoubleValue] = useState(1);
if (verdi > 3) {
  useEffect(() => setDoubleValue(verdi * 2),[verdi]);
}

return (
  <>
    <p>{`Single ${verdi} Dobbel ${dobbelverdi}`}</p>
    <button onclick="{()" > setValue(verdi + 1)}&gt;Sjekk</button>
  </>
);
}
```

Først vil du motta en advarsel fra eslint:

<code>srcFunctionComponent.js
   Linje 11:5: React Kroken "useEffect" kalles betinget. <strong>React Kroker</strong> må kalles i nøyaktig samme rekkefølge i hver komponent render .eslintreact-hooks/rules-of-hooks

Som du kan se, er det bare en eslint-advarsel, så du kan deaktivere den ved å legge til en kommando nedenfra øverst i Funksjonskomponent

/* eslint-deaktiver react-hooks/rules-of-hooks */ 

og det vil fungere, men bare til vi oppfyller betingelsen som kjører kroken vår. Det neste vi vil se er denne feilen.

Uoppdaget feil: Gjenga flere kroker enn under forrige gjengivelse.
     React 5
     FunctionComponent FunctionComponent.js:11
     React 12
     unstable_runWithPriority scheduler.development.js:468
     React 17
     js index.js:7
     js main.chunk.js:905
     Webpack 7
 react-dom.development.js:15162

Hvorfor skjer dette? React er avhengig av rekkefølgen som Hooks kalles i. React vet ikke hva som skal returneres for useEffect fordi det ikke finnes noen slik Hook i linjen som kan sjekkes.

Husk at eslint er et kraftig verktøy som hjelper oss med å fange opp mange potensielle feil. Det er farlig å deaktivere advarslene, så sjekk alltid om det å ignorere advarselen kan føre til at appen krasjer.

useState

Du vet sikkert hvordan det ser ut 😉.

const [value, setValue] = useState(0);

Så du har fire elementer: tilstand (reaktiv verdi), oppdateringsfunksjon (setter), faktisk krok (funksjon) og valgfri startverdi. Hvorfor returnerer den en matrise? Fordi vi kan restrukturere den som vi vil.

Nå vil jeg fokusere på det siste elementet - startverdien. Det er to måter å overføre den opprinnelige tilstanden på:

  1. Ved hardkodet verdi eller lignende - som vil bli kalt ved hver rendering
const [value, setValue] = useState(0);
  1. Av en funksjonsversjon. Det er veldig nyttig hvis vi ønsker å kjøre den opprinnelige tilstanden bare én gang, på den aller første gjengivelsen. Kanskje du trenger å gjøre mange komplekse beregninger for å motta den opprinnelige tilstanden? Det vil pent redusere ressurskostnadene, yay!
const [value, setValue] = useState(() => {
   console.log("INIT");
   return 0;
 });

Hvordan sjekker jeg at den første måten virkelig kalles ved hver gjengivelse? Opprett en funksjon og send den som en initial tilstand:

const checkInit = () => {
console.log("INIT");
return 0;
};

const [value, setValue] = useState(checkInit());
```

Og nå passerer du den på den andre måten:

const checkInit = () => {
console.log("INIT");
return 0;
};

const [value, setValue] = useState(() => checkInit());
```

Kult, ikke sant?

noice.png

En annen ting som kan skape feil i appflyten: Du vet sikkert hvordan du oppdaterer en tilstand, ikke sant?

setValue(1);

Ja, men hva om jeg vil oppdatere statusen basert på en tidligere status?

setValue(verdi + 1);

Ja... Men nei... Hva om du prøver å kalle setter-funksjonen to ganger, den ene etter den andre? Den anbefalte måten å oppdatere en tilstand basert på den forrige tilstanden på, er å bruke en funksjon. Det garanterer at du refererer til den forrige tilstanden

setValue((prevState) => prevState + 1);
// med objekter:
setUser((prevState) => ({ ...prevState, etternavn: "Brzeczyszczykiewicz" }));

useEffect

Denne kroken tar to argumenter (det andre er valgfritt), og vi bruker den til å håndtere sideeffekter. Avhengig av hva vi sender som det andre argumentet, vil kroken bli kalt på forskjellige måter:

  1. uten andre argument - hver gjengivelse
useEffect(() => {
   doSomething();
 });
  1. tom matrise - bare ved første gjengivelse
useEffect(() => {
   doSomething();
 }, []);
  1. med avhengigheter - hver gang verdien i avhengighetsarrayen endres
useEffect(() => {
   doSomething(verdi);
 }, [verdi]);

Opprydding

Med useEffect kan vi bruke noe som kalles cleanup. Hva er den til? Det er veldig nyttig, men jeg tror det er best for å rydde opp i hendelseslyttere. La oss si at du vil opprette en hendelseslytter som avhenger av en tilstand. Du ønsker ikke å legge til en ny hendelseslytter ved hver tilstandsendring, for etter noen få renderinger vil det være så mange lyttere at det vil påvirke appens ytelse. En god måte å unngå slike ting på er å bruke opprydningsfunksjonen. Hvordan gjør man det? Bare legg til en returfunksjon til useEffect.

useEffect(() => {
console.log("bivirkning 1", count);
return () => {
console.log("DESTROYED 1");
};
});

useEffect(() => {
console.log("bivirkning 2", count);
return () => {
console.log("DESTROYED 2");
};
}, []);

useEffect(() => {
console.log("bivirkning 3", count);
return () => {
console.log("DESTROYED 3");
};
}, [count]);
```

Fordi det er inne i useEffect Hook, kalles returen avhengig av avhengighetsarrayen - på hver gjengivelse, bare på den første gjengivelsen, eller når verdien i avhengighetsarrayen endres. Men når komponenten avmonteres, vil cleaning uansett bli kalt på det andre argumentet. Returen kode kalles før den faktiske koden fra Hook. Det er veldig logisk - først renser du den gamle, og deretter oppretter du en ny. Ikke sant?

useEffect(() => {
   // addEventListener
   console.log("Legg til");
   return () => {
     // removeEventListener
     console.log("Remove");
   };
 }, [value]);

Så først vil du motta en fjerne melding, så Legg til.

Det er én ting du må være oppmerksom på når du bruker useEffect og asynkron kode i den. Ta en titt på koden nedenfor:

useEffect(() => {
   fetch("https://picsum.photos/5000/5000").then(() => {
     setValue((prevState) => prevState + 1);
   });
 }, []);

Til å begynne med ser det ok ut. Du henter noen data, og når dataene kommer, oppdaterer du tilstanden. Og her er fellen:

Noen ganger vil du motta en slik advarsel:
Kan ikke utføre en React-tilstandsoppdatering på en umontert komponent. Dette er en no-op, men det indikerer en minnelekkasje i applikasjonen din. Du løser problemet ved å avbryte alle abonnementer og asynkrone oppgaver i en useEffect-oppryddingsfunksjon.

Årsaken er at komponenten kan avmonteres i mellomtiden, men appen vil fortsatt prøve å oppdatere tilstanden til komponenten etter at løftet er oppfylt. Hvordan håndterer man dette? Du må sjekke om komponenten eksisterer.

useEffect(() => {
let mounted = true;
fetch("https://picsum.photos/5000/5000").then(() => {
if (mounted) {
setValue((prevState) => prevState + 1);
}
});

return () => {
mounted = false;
};
}, []);
```

Merk: Det finnes en veldig lik krok => useLayoutEffect() - tilbakekallingen kjøres etter at komponenten er gjengitt, men før domen oppdateres visuelt. Det er nyttig når du arbeider med getBoundingClientRect(), men du bør bruke useEffect som standard. Hvorfor det? Fordi det kan blokkere visuelle oppdateringer - når du har en kompleks kode inne i effekten Hook.

useContext

Hva kan man bruke det til? Deling av data uten å sende props. Består av følgende elementer:

  1. Skapt kontekst - data
  2. Kontekstleverandør - gi kontekst til alle barn
  3. Overført verdi - data du ønsker å dele
  4. Hook - for å lese delte data
const bruker = {
name: "Adam",
etternavn: "Kowalski",
};

export const UserContext = createContext(user);

;
```

I child må du importere konteksten og kalle useContext-kroken og sende konteksten som et argument.

import { UserContext } fra "./App";

const { name } = useContext(UserContext);

return <h1>Hei {navn}<>
```

Voilà. Ser kult ut. Mest for overføring av globale data som temaer osv. Anbefales ikke for bruk i oppgaver med svært dynamiske endringer.

Vi kan selvfølgelig opprette en egendefinert kontekstleverandør og en egendefinert krok for å redusere boilerplate i stedet ... men jeg vil ta for meg egendefinerte kroker i neste artikkel.

useReducer

Det lar oss administrere tilstanden og gjengi på nytt når tilstanden endres - som useState. Den ligner på redux reducer. Denne er bedre enn useState når tilstandslogikken er mer komplisert.

const [state, dispatch] = useReducer(reducer, initialArg); 
  • Returnerer faktisk tilstand med en utsendelsesmetode.
  • Til forskjell fra redux spesifiseres startverdien når kroken kalles.

Det finnes også et tredje argument som kan sendes til useReducer - init-funksjonen.

const [state, dispatch] = useReducer(reducer, initialArg, init);

Hva kan den brukes til? Den kan brukes når vi ønsker å tilbakestille tilstanden til den opprinnelige verdien. Nedenfor finner du et fint eksempel:

// Foreldre
// Barn
function init(initialNumber) {
return { number: initialNumber };
}

function reducer(state, action) {
switch (action.type) {
case "change":
return { number: Math.random() };
case "reset":
return init(action.payload);
standard:
throw new Error();
}
}

export default function ChildComponent({ getFactorial }) {
const [state, dispatch] = useReducer(reducer, initialNumber, init);

return (
<>
   <h2>Nummer: {state.number}</h2>
      <button
        onclick="{()" > dispatch({ type: "reset", payload: initialNumber })} }
      &gt;
        Tilbakestill
      </button>
      <button onclick="{()" > dispatch({ type: "change" })}&gt;Tegn</button>
    </>
  );
}

Nummer: {state.number}

ReducerInit.png

useCallback

Når skal man bruke det? Når vi ønsker å oppnå referanselikhet (og dermed redusere antallet opprettede funksjoner). Denne kroken returnerer funksjonen, i motsetning til useMemo som returnerer verdien.

Eksempel: Opprett en funksjon i den overordnede komponenten, og send den deretter via props

// Parent
 const getSquaredValue = () => count * count;
 ...
 return (
   >.
 )

Sjekk deretter i underordnet komponent hvor mange ganger effekten Hook vil bli kalt etter at funksjonen er lagt til i avhengighetsarrayen:

// Barn
 useEffect(() => {
   console.log("getSquaredValue", getSquaredValue());
 }, [getSquaredValue]);

Den vil logge til konsollen ved hver gjengivelse! Selv om verdiene inne i getSquaredValue() funksjonen ble ikke endret. Men vi kan unngå dette ved å pakke inn funksjonen i useCallback

const getSquaredValue = useCallback(() => count * count, [count])

Vi kan også sende noen parametere til denne funksjonen:

const getSquaredValue = useCallback(
   (multiplikator) => count * count * multiplikator,
   [count]
 );

brukMemo

const memoizedValue = useMemo(() => {
   return doSomething(verdi);
 }, [verdi]);
  • Det er ikke nøytralt når man ser på ressurskostnadene - useMemo må kalles ved hver gjengivelse, lagrer verdien i minnet og sammenligner (minneoverhead),
  • bruker Memoization - optimaliseringsteknikken, en spesifikk form for hurtigbufring.

Du bør bare bruke den i to scenarier:

  1. Hvis du vil unngå å kalle en kompleks kode ved hver gjengivelse;
  2. Hvis du ønsker å oppnå referansemessig likhet.

La oss se litt nærmere på det andre tilfellet. Vi ønsker å bruke useEffect med et objekt som en avhengighet. Fordi objekter sammenlignes ved hjelp av referansen, vil useEffect bli kalt ved hver rendering. For å unngå slike ting kan vi kombinere useEffect med useMemo for å memotisere slike objekter og deretter sende de memotiserte objektene til avhengighetsarrayen. Kort eksempel:

Prøv først å gjøre det uten useMemo:

const hobbit = { navn: "Bilbo" };

useEffect(() => {
console.log("Hello ", hobbit.name);
}, [hobbit]);
```

Du vil også motta en advarsel:

Hobbit-objektet gjør at avhengigheten til useEffect-kroken (linje 49) endres ved hver rendering. Flytt den inn i useEffect-tilbakekallet. Alternativt kan du pakke inn initialiseringen av 'hobbit' i sin egen useMemo ()-krok.eslintreact-hooks/exhaustive-deps

Prøv deretter med useMemo:

const hobbit = useMemo(() => {
return { navn: "Bilbo" };
}, []);

useEffect(() => {
console.log("Hello ", hobbit.name);
}, [hobbit]);
```

useRef

Det viktigste: useRef utløser ikke ny gjengivelse (som useState) fordi den ikke er koblet til gjengivelsessyklusen - den beholder den samme referansen mellom gjengivelser.

const ref = useRef(0);

For å hente den lagrede verdien må du bruke en aktuell egenskap (ref er et objekt) - -. ref.strøm

Det andre tilfellet vi kan bruke denne kroken til, er å referere til elementer i HTML. Hvert element har et ref-attributt. Så vi kan håndtere fokus, hendelser osv.

Det tredje tilfellet er at vi kan bruke refs til å håndtere ukontrollerte komponenter. Du kan lese mer om dem i react-dokumenter,
men kort fortalt ser det slik ut:

export default function UkontrollertForm() {
  const input = useRef();

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(input.current.value);
  };

  return (
     
      
      Send </form
     </form
  );
}

Som du ser, er det ingen hendelsesbehandler, den husker bare den inntastede verdien. Den er perfekt for å håndtere enkle skjemaer når du bare vil lese lagrede verdier når du trenger dem (for eksempel når du sender inn).

Bonus: Det er flott når du trenger å huske tidligere tilstandsverdier. Du kan bruke useEffect Hook, bare send tilstanden til ref.

const [value, setValue] = useState("");

let prevValue = useRef("");

useEffect(() => {
  prevValue.current = verdi;
}, [verdi]);

 setValue(e.target.value)}>;

Som du ser, er Hooks ikke så opplagte. Vi kan kombinere dem for å løse mange problemer. Du vil helt sikkert ha stor nytte av å studere dette emnet.

Og det finnes også tilpassede kroker...

For å oppsummere, React kroker har revolusjonert måten React-utviklere tilnærming bygning webapplikasjoner . Ved å tilby en mer intuitiv og effektiv måte å administrere tilstand og livssyklus i funksjonelle komponenter på, har hooks blitt en integrert del av React-utvikling .

Enten du er en erfaren utvikler eller nettopp har begynt med React, er det avgjørende å forstå de mest populære krokene og deres bruksområder. Med kroker som useState, useEffect, useContext og flere, React-komponenter kan bygges med renere og mer gjenbrukbar kode. I tillegg gir muligheten til å lage tilpassede kroker gjør det mulig for utviklere å kapsle inn og dele logikk på tvers av flere komponenter, noe som fremmer gjenbruk av kode og modularitet. Etter hvert som React fortsetter å utvikle seg og introdusere nye funksjoner, vil hooks utvilsomt spille en sentral rolle når det gjelder å utnytte det fulle potensialet i rammeverket.

Så uansett om du jobber med en liten funksjonsapp eller en storstilt webapplikasjon, er det viktig å omfavne React kroker vil forbedre arbeidsflyten din og åpne opp for en mengde muligheter for å skape robuste og funksjonsrike React-applikasjoner .

Slutten av del 1

Les mer om dette:

JavaScript er helt død. En fyr på Internett

Distribuere GraphQL/MongoDB API ved hjelp av Netlify-funksjoner

Slik dreper du et prosjekt med dårlig kodingspraksis

Relaterte artikler

Programvareutvikling

Bygg fremtidssikre webapper: Innsikt fra The Codests ekspertteam

Oppdag hvordan The Codest utmerker seg når det gjelder å skape skalerbare, interaktive webapplikasjoner med banebrytende teknologi som gir sømløse brukeropplevelser på tvers av alle plattformer. Finn ut hvordan ekspertisen vår driver digital transformasjon og...

THECODEST
Programvareutvikling

Topp 10 Latvia-baserte programvareutviklingsselskaper

I vår nyeste artikkel kan du lese mer om Latvias beste programvareutviklingsselskaper og deres innovative løsninger. Oppdag hvordan disse teknologilederne kan bidra til å løfte virksomheten din.

thecodest
Løsninger for bedrifter og oppskalering

Grunnleggende om Java-programvareutvikling: En guide til vellykket outsourcing

Utforsk denne viktige veiledningen om vellykket outsourcing av Java-programvareutvikling for å øke effektiviteten, få tilgang til ekspertise og drive frem prosjektsuksess med The Codest.

thecodest
Programvareutvikling

Den ultimate guiden til outsourcing i Polen

Den kraftige økningen i outsourcing i Polen er drevet av økonomiske, utdanningsmessige og teknologiske fremskritt, noe som fremmer IT-vekst og et forretningsvennlig klima.

TheCodest
Løsninger for bedrifter og oppskalering

Den komplette guiden til verktøy og teknikker for IT-revisjon

IT-revisjoner sørger for sikre, effektive og kompatible systemer. Les hele artikkelen for å lære mer om viktigheten av dem.

The Codest
Jakub Jakubowicz CTO og medgrunnlegger

Abonner på vår kunnskapsbase og hold deg oppdatert på ekspertisen fra IT-sektoren.

    Om oss

    The Codest - Internasjonalt programvareutviklingsselskap med teknologisentre i Polen.

    Storbritannia - Hovedkvarter

    • Kontor 303B, 182-184 High Street North E6 2JA
      London, England

    Polen - Lokale teknologisentre

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warszawa, Polen

      The Codest

    • Hjem
    • Om oss
    • Tjenester
    • Casestudier
    • Vet hvordan
    • Karriere
    • Ordbok

      Tjenester

    • Det rådgivende
    • Programvareutvikling
    • Backend-utvikling
    • Frontend-utvikling
    • Staff Augmentation
    • Backend-utviklere
    • Ingeniører i skyen
    • Dataingeniører
    • Annet
    • QA-ingeniører

      Ressurser

    • Fakta og myter om samarbeid med en ekstern programvareutviklingspartner
    • Fra USA til Europa: Hvorfor velger amerikanske oppstartsbedrifter å flytte til Europa?
    • Sammenligning av Tech Offshore Development Hubs: Tech Offshore Europa (Polen), ASEAN (Filippinene), Eurasia (Tyrkia)
    • Hva er de største utfordringene for CTO-er og CIO-er?
    • The Codest
    • The Codest
    • The Codest
    • Retningslinjer for personver
    • Vilkår for bruk av nettstedet

    Opphavsrett © 2025 av The Codest. Alle rettigheter forbeholdt.

    nb_NONorwegian
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek nb_NONorwegian