Unngå ytelsesproblemer med Context
Identifiser unødvendige nye gjengivelser som skyldes endringer i kontekstverdier, del konteksten i flere providere og memoiser kontekstverdier for å optimalisere ytelsen.
Unngå ytelsesproblemer med Context er en gratis leksjon i React Native Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i React Native Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i React Native Academy inneholder totalt 4 leksjoner.
Problemet med nye gjengivelser i kontekst
Når en Context Provider gjengis på nytt med en ny value, gjengis alle komponenter som kaller useContext for denne konteksten, på nytt, uavhengig av om den spesifikke delen av verdien de bruker, er endret. I store apper med mange komponenter som bruker konteksten kan dette føre til betydelige ytelsesproblemer.
Finne unødvendige nye gjengivelser i kontekst
Bruk React DevTools Profiler til å finne komponenter som gjengis på nytt for ofte. Registrer en interaksjon som bare skal påvirke én del av brukergrensesnittet, og undersøk deretter hvilke komponenter som er markert i flammegrafen. Hvis komponenter som bare leser én del av konteksten, gjengis på nytt når en annen del endres, har De et ytelsesproblem.
Antimønsteret med innebygde objekter
Den vanligste årsaken til unødvendige nye gjengivelser i kontekst er at verdien opprettes direkte i JSX. Da opprettes en ny objektreferanse ved hver gjengivelse av Provideren, og React tolker dette som en endret verdi – selv når innholdet er identisk – noe som utløser nye gjengivelser hos alle komponentene som bruker konteksten.
// Bad: new object on every render
<MyContext.Provider value={{ user, logout }}>
// Good: stable reference with useMemo
const value = useMemo(() => ({ user, logout }), [user, logout]);
<MyContext.Provider value={value}>Memoisere kontekstverdier med useMemo
Pakk kontekstverdien inn i useMemo inne i Provideren. React oppretter bare et nytt objekt, og varsler dermed komponentene som bruker konteksten, når én av de oppførte avhengighetene endres. Dette er den enkleste og mest effektive løsningen på ytelsesproblemer med kontekst.
function CartProvider({ children }) {
const [items, setItems] = useState([]);
const addItem = useCallback((item) => {
setItems((prev) => [...prev, item]);
}, []);
const value = useMemo(() => ({
items,
addItem,
total: items.reduce((sum, i) => sum + i.price, 0),
}), [items, addItem]);
return <CartContext.Provider value={value}>{children}</CartContext.Provider>;
}Dele kontekster for uavhengige ansvarsområder
Hvis konteksten inneholder både verdier som endres ofte (for eksempel antall varer i handlekurven) og verdier som sjelden endres (for eksempel brukerprofilen), tvinges komponenter som bare trenger de stabile dataene, til å gjengis på nytt hver gang de flyktige dataene endres. Løsningen er å dele konteksten i to separate providere – én for hvert ansvarsområde.
// Instead of one big UserContext:
export const UserDataContext = createContext(null); // changes rarely
export const UserActionsContext = createContext(null); // changes rarely
export const CartItemsContext = createContext([]); // changes often
// Consumers only subscribe to what they useSkille tilstand fra utsending
Et velprøvd mønster er å dele konteksten i en tilstandskontekst og en utsendingskontekst. Utsendingsfunksjoner endres aldri (useCallback eller utsending fra useReducer er stabile), så komponenter som bare sender handlinger, gjengis aldri på nytt på grunn av tilstandsendringer. Bare komponenter som leser tilstanden, gjengis på nytt når den endres.
export const AppStateContext = createContext(null);
export const AppDispatchContext = createContext(null);
function AppProvider({ children }) {
const [state, dispatch] = useReducer(appReducer, initialState);
return (
<AppStateContext.Provider value={state}>
<AppDispatchContext.Provider value={dispatch}>
{children}
</AppDispatchContext.Provider>
</AppStateContext.Provider>
);
}React.memo hjelper IKKE komponenter som bruker kontekst
En vanlig feil er å pakke komponenter som bruker kontekst, inn i React.memo i troen på at det hindrer nye gjengivelser som skyldes kontekstendringer. Det gjør det ikke – React.memo sammenligner bare props, ikke kontekstabonnementer. En komponent som bruker kontekst, gjengis alltid på nytt når kontekstverdien endres, uavhengig av React.memo.
// React.memo does NOT prevent context-driven re-renders
const MyComponent = React.memo(() => {
const { value } = useContext(MyContext);
// Still re-renders every time MyContext changes
return <Text>{value}</Text>;
});
// Solution: Split context or memoize the value in the ProviderSelektormønster for kontekst
Hvis De trenger detaljerte abonnementer, tilsvarende Redux sin useSelector, kan De implementere et enkelt selektormønster. En egendefinert hook tar imot en selektorfunksjon og memoiserer den valgte verdien med useMemo. Nye gjengivelser skjer bare når den valgte verdien endres, ikke når hele konteksten endres.
function useCartTotal() {
const { items } = useContext(CartContext);
// Only recomputes when items changes
return useMemo(
() => items.reduce((sum, item) => sum + item.price, 0),
[items]
);
}
// Component only re-renders when the total number changes
function CartBadge() {
const total = useCartTotal();
return <Text>${total.toFixed(2)}</Text>;
}Holde providere enkle
Selve Provider-komponenten bør være så enkel som mulig. Flytt kostbare beregninger ut av gjengivelsen av Provideren, inn i useMemo eller inn i reduceren. Unngå å hente data, kjøre omfattende transformasjoner eller opprette store objekter direkte i Provider-komponentens JSX ved hver gjengivelse.
Komposisjon fremfor én stor kontekst
Unngå fristelsen til å legge all global tilstand i appen i én enkelt kontekst. En bedre arkitektur bruker mange små, fokuserte kontekster: AuthContext for autentisering, ThemeContext for farger, CartContext for handlekurven og NotificationContext for varsler. Hver kontekst gjengir bare sine egne komponenter på nytt, slik at omfanget av hver nye gjengivelse blir lite og forutsigbart.
// Architecture with focused contexts
export default function App() {
return (
<AuthProvider>
<ThemeProvider>
<CartProvider>
<NotificationProvider>
<AppContent />
</NotificationProvider>
</CartProvider>
</ThemeProvider>
</AuthProvider>
);
}Når De bør vurdere Zustand eller Redux
Hvis ytelsesoptimaliseringer for kontekst blir for komplekse – eller hvis De oppdager at De bygger et omfattende selektorsystem – bør De vurdere å bytte til Zustand eller Redux Toolkit. Disse bibliotekene tilbyr detaljerte abonnementer direkte og er utviklet for tilstandshåndtering i stor skala. Kontekst er fortsatt ideelt for enkle globale verdier som tema, autentisering og innstillinger.
Hurtigsjekk
Test forståelsen Deres av hvordan man unngår ytelsesproblemer med kontekst fra denne leksjonen.
Oppsummering av leksjonen
I denne leksjonen har De lært at: innebygde verdiobjekter i Provider-ens JSX fører til unødvendige nye gjengivelser – bruk useMemo for å stabilisere dem, store kontekster bør deles inn i mindre, fokuserte kontekster for å begrense omfanget av nye gjengivelser, og tilstand og utsending bør deles i to kontekster, slik at komponenter som bare sender handlinger, aldri gjengis på nytt ved tilstandsendringer. Deretter skal vi se på useEffect-hooken og avhengighetsmatriser for datainnhenting.
Lær deg JavaScript med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 30
- Leksjoner
- 120
Ofte stilte spørsmål
Er leksjonen «Unngå ytelsesproblemer med Context» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien React Native Academy, inkludert «Unngå ytelsesproblemer med Context», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i React Native Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Unngå ytelsesproblemer med Context»?
Identifiser unødvendige nye gjengivelser som skyldes endringer i kontekstverdier, del konteksten i flere providere og memoiser kontekstverdier for å optimalisere ytelsen. Du øver på React Native Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med React Native Academy?
Ingen tidligere erfaring er nødvendig. React Native Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «Unngå ytelsesproblemer med Context»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne React Native Academy-leksjonen?
Ja. Alle React Native Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Opprette og tilby en kontekst
- Bruke kontekst med useContext
- En temakontekst med bryter for mørk modus
- Unngå ytelsesproblemer med Context