Reager skalKomponentOpdater afmystificeret

Under udvikling i React har du nogensinde spekuleret på, hvornår og hvorfor en komponents render () -metode køres? Eller hvornår skal man bruge mindre indlysende livscyklusmetoder, børComponentUpdate ()?

Hvis svaret er ja, har din app muligvis problemer med ydeevnen. Læs igennem, og du kan nemt rette dem.

Det hele kommer ned på, hvordan React fungerer under emhætten. React's store løfte er, at det flammer hurtigt ved at gengive elementer på en side.

For at gøre dette gemmer React to versioner af DOM i hukommelsen:

  • den version af DOM, der aktuelt vises
  • den næste version af DOM, der skal vises

Den sammenligner de to og opdaterer den viste DOM med kun de dele, der er ændret. Denne proces kaldes træafstemning. Roden til træet, der evalueres til forsoning, er en komponent, som rekvisitter har ændret.

Store. Uanset om du planlagde det eller ej, følger din webapp containeren / præsentationskomponenterne i nogen grad opdelt. Se her og her for definitioner. Dette betyder, at hver kompleks visning i din app er lavet af en containerkomponent, der har logikken og har meget kun visning af komponenter som børn.

Dette er et meget godt mønster. Hvis du ser nærmere på, betyder det dog, at enhver brugerinteraktion i udsigten vil påvirke selve containeren og udløse en gengivelse af den og alle dens børn. Sig, at du har en liste over elementer med en flot visning af tekst, billede og en "Tilføj til favoritter" gul stjerne-lignende knap. Den minimale model for et listeelement kan være:

product = { imageUrl: '...', title: '...', isFavourite: false }

Listen over favoritter kan komme fra en anden datakilde. Uanset hvad ser din komponentorganisation sandsynligvis sådan ud:

Handleren kaldes ved brugerklik og gemmer siden til infoserveren (eller vedvarer i en butik eller hvad som helst) og udløser en ændring i this.props.elements.

Resultatet af et enkelt klik udløser gengivelsen af ​​containeren og alle rækkerne på listen bare for at opdatere et afkrydsningsfelt.

Det er her, shouldComponentUpdate () kommer i spil. Du kan fortælle React om ikke at gengive rækker, der ikke behøver at bruge denne metode.

class ListItem extends Component { shouldComponentUpdate(nextProps, nextState) { return nextProps.isFavourite != this.props.isFavourite; } ... }

Her er en konkret sag: på et markedsplads-app-projekt havde vi en produktstyringsvisning for sælgerne. Listen havde et "indlæs mere, når brugeren ruller ned" -mønster, og en integreret elementhandling "viser / skjuler" for at indstille synligheden af ​​hvert produkt. Alt var fint, når sælgere administrerede <100 produkter i deres dashboard. Derefter begyndte en given sælger at komme ind og reklamere for mere end 300 produkter ...

Der var en forsinkelse på ~ 600 ms, før brugergrænsefladen blev opdateret, efter at en bruger havde klikket på ikonet "aktiver / deaktiver". Forsinkelsen var bestemt synlig af slutbrugeren. Ved hjælp af Chrome-profilen så vi, at det tog React ~ 2ms at gengive en enkelt række. Gange 300 ... vi fik op til 600 ms. Vi tilføjede kontrollerne shouldComponentUpdate () for de korrekte forhold. Gengivelsestiden efter brugerens klik blev under 10 ms ...

Jeg har sammensat et lille projekt, der gør det muligt at gengive denne sag her. Kør det og læs kodekommentarerne for at se magien ske.

Advarsel til Redux-brugere

Problemet beskrevet ovenfor kan forekomme oftere, hvis du bruger Redux og vælger igen (eller lignende "butiksbaserede" handlingsrørledningsbiblioteker).

Med Redux og genvalg vælger du handlinger til butikken, og du tilslutter lyttere til at gemme ændringer, også kaldet vælgere. Selektorer er globalt tilgængelige i applikationen, og i en stor applikation er det ret nemt for mange komponenter at kortlægge til de samme vælgere. Ændringer i butikken kan udløse rekvisitaændringer og gør således, at det er fuldstændig irrelevant for nogle komponenter.

Her er det forvirrende råd: Brug ikke shouldComponentUpdate () til at forhindre gengivelser i sådanne tilfælde. Logikken indeni shouldComponentUpdate bør kun se på, hvad der er relevant for komponenten. Det skal aldrig foregribe de sammenhænge, ​​komponenten bruges i. Årsagen er bare, at din kode hurtigt bliver uvedligeholdelig.

Hvis du har denne slags problemer, betyder det, at din butiksstruktur er forkert, eller at vælgerne ikke er specifikke nok. Du skal komme til en ny modelleringsrunde.

Jeg anbefaler disse fantastiske retningslinjer for kogeplader. Det fremmer indkapsling af butikker pr. Container på højt niveau med et globalt område til de vigtigste datastrukturer, der spænder over hele applikationen. Dette er en ret sikker tilgang til at undgå fejl i butiksmodellering.

Tak for læsningen! Hvis du kunne lide det, skal du trykke på klappeknappen nedenfor. Det hjælper andre mennesker med at se historien.