Separasjon av bekymringer med React-kroker PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Separasjon av bekymringer med React-kroker

Hvis du har jobbet med React en stund, har du sannsynligvis kommet over container og presentasjonskomponenter , eller smarte og dumme komponenter. Disse begrepene beskriver en mønster som skiller UI-laget av React-komponenter fra logikken.

Å skille brukergrensesnittet fra forretningslogikken er ikke noe unikt for React: separasjon av bekymringer er et designprinsipp som har eksisterte allerede på 70-tallet. For eksempel er det vanlig praksis å skille koden som får tilgang til databasen fra forretningslogikken på backend.

Så i React løste vi dette problemet ved å lage containerkomponenter som inneholder all logikken, som deretter vil overføre dataene via rekvisitter til presentasjonskomponenten.

Med introduksjonen av React-kroker er det en ny tilnærming til dette: å bruke tilpassede kroker.

Hvorfor skal vi skille logikken fra komponenten?

Før vi begynner å koble logikken fra våre React-komponenter, bør vi vite hvorfor.

Å organisere koden vår på en måte der hver funksjon eller komponent bare er ansvarlig for én ting har fordelen at det er mye lettere å endre og vedlikeholde (Dave og Andrew kaller dette "ortogonalitet" i boken deres Den pragmatiske programmereren).

Å bruke dette på React betyr at komponenten vår vil se renere og mer organisert ut. Vi trenger ikke å rulle forbi veggen av logikk før vi redigerer brukergrensesnittet, for eksempel.

Å organisere koden din på denne måten gjør den ikke bare bedre og enklere å navigere, det gjør det også enklere å endre siden endring av kroken ikke påvirker brukergrensesnittet og omvendt.

Testing er også mer tilgjengelig: vi kan teste logikken separat fra brukergrensesnittet hvis vi vil. Den viktigste fordelen for meg er imidlertid hvordan denne tilnærmingen organiserer koden min.

Hvordan koble fra logikk med React-kroker

For å koble logikken fra komponenten vår, vil vi først lage en tilpasset krok.

La oss ta denne komponenten som et eksempel. Den beregner eksponentialverdien til grunntallet og eksponenten:

Du kan finne den fullstendige kildekoden her..

Koden ser slik ut:

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 kan se bra ut allerede, men for denne veiledningens skyld, bare forestille at det er mer logikk her inne.

Som et første skritt vil vi flytte logikken til en tilpasset krok og kall det inne i komponenten vår.

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 kroken til en egen fil for en mer fremtredende separasjon av bekymringer.

I tillegg kan vi dele kroken vår i mindre, gjenbrukbare funksjoner. I dette tilfellet kan vi bare trekke ut 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);

  // ...
};

Å teste disse funksjonene er mye enklere enn å teste hele komponentens kode fra det første eksemplet. Vi kan teste dem med hvilket som helst Node.js-testbibliotek, som ikke engang trenger å støtte React-komponenter.

Vi har nå vår rammespesifikke kode (React) i koden for komponenten og kroken, mens forretningslogikken vår lever i de forskjellige funksjonene vi definerte senere (som er rammeverk-agnostiske).

Beste praksis

Navngi

Jeg liker å navngi mine tilpassede kroker etter komponenten som en sammenkobling av use og komponentens navn (f.eks useExponentCalculator). Jeg ringer da fil det samme som kroken.

Det kan være lurt å følge en annen navnekonvensjon, men jeg anbefaler holde seg konsekvent i prosjektet ditt.

Hvis jeg kan gjenbruke deler av en tilpasset krok, flytter jeg den vanligvis til en annen fil under src/hooks.

Ikke overdriv

Prøv å være pragmatisk. Hvis en komponent bare har noen få linjer med JS, er det ikke nødvendig å skille logikken.

CSS-i-JS

Hvis du bruker et CSS-in-JS-bibliotek (useStyles), kan det være lurt å flytte denne koden til en annen fil også.

Du kan flytte den inn i samme fil som kroken. Imidlertid foretrekker jeg enten å beholde den over komponenten i samme fil eller flytte den til sin egen fil hvis den blir for stor.

konklusjonen

Enten du tror at bruk av tilpassede kroker forbedrer koden din eller ikke, til syvende og sist kommer det ned til personlige preferanser. Hvis kodebasen din ikke inneholder mye logikk, vil ikke fordelene med dette mønsteret være for relevante for deg.

Tilpassede kroker er bare én måte å øke modulariteten på; Jeg vil også anbefale på det sterkeste dele opp komponenter og funksjoner i mindre, gjenbrukbare biter når mulig.

Temaet diskuteres også på et mer generelt nivå i Den pragmatiske programmereren. Jeg skrev en artikkel som dekker favorittemnene mine i boken, så hvis det interesserer deg, sørg for å gjøre det sjekk det ut.

Tidstempel:

Mer fra Codementor React Fakta