Adskillelse af bekymringer med React hooks PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Adskillelse af bekymringer med React kroge

Hvis du har arbejdet med React i et stykke tid, er du sikkert stødt på container , præsentationskomponenter , eller smarte og dumme komponenter. Disse udtryk beskriver en mønster der adskiller UI-laget af React-komponenter fra logikken.

At adskille brugergrænsefladen fra forretningslogikken er ikke noget unikt for React: adskillelse af bekymringer er et designprincip, der har allerede eksisteret i 70'erne. For eksempel er det almindelig praksis at adskille koden, der får adgang til databasen, fra forretningslogikken på backend.

Så i React løste vi dette problem ved at skabe containerkomponenter, der indeholder al logikken, som derefter ville videregive dataene via rekvisitter til præsentationskomponenten.

Med introduktionen af ​​React hooks er der en ny tilgang til dette: at bruge tilpassede kroge.

Hvorfor skal vi adskille logikken fra komponenten?

Før vi begynder at afkoble logikken fra vores React-komponenter, bør vi vide hvorfor.

At organisere vores kode på en måde, hvor hver funktion eller komponent kun er ansvarlig for én ting, har den fordel, at det er meget nemmere at ændre og vedligeholde (Dave og Andrew kalder dette "ortogonalitet” i deres bog Den pragmatiske programmør).

At anvende dette på React betyder, at vores komponent vil se renere og mere organiseret ud. Vi behøver for eksempel ikke at rulle forbi logikkens mur, før vi redigerer brugergrænsefladen.

At organisere din kode på denne måde får den ikke kun til at se bedre og nemmere at navigere i, det gør det også nemmere at ændre, da ændring af krogen ikke påvirker brugergrænsefladen og omvendt.

Test er også mere tilgængeligt: ​​vi kan teste logikken separat fra brugergrænsefladen, hvis vi vil. Den største fordel for mig er imidlertid, hvordan denne tilgang organiserer min kode.

Sådan afkobles logik med React-kroge

For at afkoble logikken fra vores komponent, vil vi først oprette en tilpasset krog.

Lad os tage denne komponent som et eksempel. Den beregner den eksponentielle værdi af grundtallet og eksponenten:

Du kan finde den komplette kildekode link..

Koden ser sådan ud:

export const ExponentCalculator = () => {
  const [base, setBase] = useState(4);
  const [exponent, setExponent] = useState(4);
  const result = (base ** exponent).toFixed(2);

  const handleBaseChange = (e) => {
    e.preventDefault();
    setBase(e.target.value);
  };

  const handleExponentChange = (e) => {
    e.preventDefault();
    setExponent(e.target.value);
  };

  return (
    <div className="blue-wrapper">
      <input
        type="number"
        className="base"
        onChange={handleBaseChange}
        placeholder="Base"
        value={base}
      />
      <input
        type="number"
        className="exponent"
        onChange={handleExponentChange}
        placeholder="Exp."
        value={exponent}
      />
      <h1 className="result">{result}</h1>
    </div>
  );
};

Dette ser måske allerede fint ud, men for denne tutorials skyld, bare billede at der er mere logik herinde.

Som et første skridt vil vi flytte logikken til en tilpasset hook og kalder det inde i vores komponent.

const useExponentCalculator = () => {
  const [base, setBase] = useState(4);
  const [exponent, setExponent] = useState(4);
  const result = (base ** exponent).toFixed(2);

  const handleBaseChange = (e) => {
    e.preventDefault();
    setBase(e.target.value);
  };

  const handleExponentChange = (e) => {
    e.preventDefault();
    setExponent(e.target.value);
  };

  return {
    base,
    exponent,
    result,
    handleBaseChange,
    handleExponentChange,
  };
};

export const ExponentCalculator = () => {
  const {
    base,
    exponent,
    result,
    handleExponentChange,
    handleBaseChange,
  } = useExponentCalculator();

  // ...
};

Vi kunne flytte denne krog til en separat fil for en mere fremtrædende adskillelse af bekymringer.

Derudover kan vi yderligere adskille vores krog i mindre, genanvendelige funktioner. I dette tilfælde kan vi kun udtrække calculateExponent.

useExponentCalculator.js

const calculateExponent = (base, exponent) => base ** exponent;

const useExponentCalculator = () => {
  const [base, setBase] = useState(4);
  const [exponent, setExponent] = useState(4);
  const result = calculateExponent(base, exponent).toFixed(2);

  // ...
};

Det er meget nemmere at teste disse funktioner end at teste hele komponentens kode fra det første eksempel. Vi kunne teste dem med et hvilket som helst Node.js-testbibliotek, som ikke engang behøver at understøtte React-komponenter.

Vi har nu vores rammespecifikke kode (React) i koden til komponenten og krogen, mens vores forretningslogik lever i de forskellige funktioner, vi definerede senere (som er rammeagnostiske).

Bedste praksis

Navngivning

Jeg kan godt lide at opkalde mine tilpassede kroge efter komponenten som en sammenkædning af use og komponentens navn (f.eks useExponentCalculator). Så ringer jeg til fil det samme som krogen.

Du vil måske følge en anden navnekonvention, men jeg anbefaler forblive konsekvent i dit projekt.

Hvis jeg kan genbruge dele af en tilpasset krog, flytter jeg den normalt til en anden fil under src/hooks.

Overdriv det ikke

Prøv at være pragmatisk. Hvis en komponent kun har nogle få linjer JS, er det ikke nødvendigt at adskille logikken.

CSS-i-JS

Hvis du bruger et CSS-i-JS-bibliotek (useStyles), vil du måske også flytte denne kode til en anden fil.

Du kan flytte den ind i den samme fil som krogen. Jeg foretrækker dog enten at beholde den over komponenten i samme fil eller flytte den til sin egen fil, hvis den bliver for stor.

Konklusion

Uanset om du tror, ​​at brug af tilpassede kroge forbedrer din kode eller ej, kommer det i sidste ende ned til personlige præferencer. Hvis din kodebase ikke indeholder en masse logik, vil fordelene ved dette mønster ikke være for relevante for dig.

Brugerdefinerede kroge er kun én måde at øge modulariteten på; Jeg vil også varmt anbefale opdele komponenter og funktioner i mindre, genanvendelige bidder når det er muligt.

Emnet diskuteres også på et mere generelt plan i Den pragmatiske programmør. Jeg skrev en artikel, der dækker mine yndlingsemner i bogen, så hvis det interesserer dig, så sørg for det tjek det ud.

Tidsstempel:

Mere fra Kodementor-reaktionsfakta