Undgåelse af ydeevneproblemer med context
Identificér unødvendige renders, der skyldes ændringer i context-værdier, opdel context i flere providere, og memoizér context-værdier for at optimere ydeevnen.
Undgåelse af ydeevneproblemer med context er en gratis React Native Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i React Native Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. React Native Academy-kurset indeholder 4 lektioner i alt.
Problemet med ny rendering af konteksten
Når Context Provider renderes igen med en ny value, renderes alle komponenter, der kalder useContext for den pågældende kontekst, igen, uanset om den specifikke del af værdien, de bruger, er ændret. I store apps med mange komponenter, der bruger konteksten, kan det føre til betydelige problemer med ydeevnen.
Diagnosticering af unødvendig ny rendering af konteksten
Brug React DevTools Profiler til at identificere komponenter, der renderes igen for ofte. Optag en interaktion, som kun burde påvirke én del af brugerfladen, og undersøg derefter, hvilke komponenter der er fremhævet i flammegrafen. Hvis komponenter, der kun læser én del af konteksten, renderes igen, når en ikke-relateret del ændres, har du et problem med ydeevnen.
Anti-mønsteret med et indlejret objekt
Den mest almindelige årsag til unødvendig ny rendering af konteksten er, at værdien oprettes direkte i JSX. Det opretter en ny objektreference ved hver rendering af provideren, hvilket React opfatter som en ændret værdi — selv når indholdet er identisk — og udløser en kædereaktion af nye renderinger hos alle komponenter, der bruger 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}>Memoisering af kontekstværdier med useMemo
Omslut kontekstobjektet med useMemo inde i provideren. React opretter kun et nyt objekt og underretter dermed kun komponenterne, der bruger konteksten, når en af de angivne afhængigheder ændres. Det er den enkleste og mest effektive løsning på problemer med kontekstens ydeevne.
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>;
}Opdeling af kontekster efter uafhængige ansvarsområder
Hvis din kontekst både indeholder værdier, der ændres ofte (f.eks. antallet af varer i indkøbskurven), og værdier, der sjældent ændres (f.eks. brugerprofilen), tvinges komponenter, der kun har brug for de stabile data, til at blive renderet igen, hver gang de svingende data ændres. Løsningen er at opdele 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 useAdskillelse af tilstand og afsendelse
Et gennemprøvet mønster er at opdele konteksten i en tilstandskontekst og en afsendelseskontekst. Afsendelsesfunktioner ændres aldrig (useCallback eller dispatch fra useReducer er stabile), så komponenter, der kun sender handlinger, renderes aldrig igen på grund af ændringer i tilstanden. Kun komponenter, der læser tilstanden, renderes igen, når den ændres.
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 hjælper IKKE komponenter, der bruger kontekst
En almindelig fejl er at omslutte komponenter, der bruger kontekst, med React.memo i den tro, at det forhindrer nye renderinger på grund af kontekstændringer. Det gør det ikke — React.memo sammenligner kun props, ikke konteksttilmeldinger. En komponent, der bruger kontekst, renderes altid igen, når kontekstværdien ændres, uanset 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 ProviderVælgermønsteret for kontekst
Hvis du har brug for detaljerede tilmeldinger, der minder om Redux' useSelector, kan du implementere et enkelt vælgermønster. En brugerdefineret hook modtager en vælgerfunktion og memorerer den valgte værdi med useMemo. Nye renderinger sker kun, når den valgte værdi ændres, ikke når hele konteksten ændres.
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>;
}Hold providere enkle
Selve Provider-komponenten bør være så enkel som muligt. Flyt beregninger, der kræver mange ressourcer, ud af providerens rendering og ind i useMemo eller reduceren. Undgå at hente data, udføre tunge transformationer eller oprette store objekter direkte i providerens JSX ved hver rendering.
Sammensætning frem for én stor kontekst
Undgå fristelsen til at placere hele appens globale tilstand i én enkelt kontekst. En bedre arkitektur bruger mange små, fokuserede kontekster: AuthContext til godkendelse, ThemeContext til farver, CartContext til indkøbskurven og NotificationContext til beskeder. Hver kontekst renderer kun sine egne komponenter igen, så omfanget af hver ny rendering forbliver lille og forudsigeligt.
// Architecture with focused contexts
export default function App() {
return (
<AuthProvider>
<ThemeProvider>
<CartProvider>
<NotificationProvider>
<AppContent />
</NotificationProvider>
</CartProvider>
</ThemeProvider>
</AuthProvider>
);
}Hvornår du bør overveje Zustand eller Redux
Hvis optimering af kontekstens ydeevne bliver for kompleks — eller hvis du opdager, at du er ved at opbygge et omfattende vælgersystem — bør du overveje at skifte til Zustand eller Redux Toolkit. Disse biblioteker tilbyder detaljerede tilmeldinger direkte fra start og er udviklet til tilstandshåndtering i stor skala. Context er stadig ideel til enkle globale værdier som tema, godkendelse og præferencer.
Hurtig kontrol
Test din forståelse af, hvordan du undgår problemer med kontekstens ydeevne i denne lektion.
Opsummering af lektionen
I denne lektion har du lært, at: indlejrede værdiobjekter i Provider-JSX forårsager unødvendige nye renderinger — brug useMemo til at stabilisere dem, store kontekster bør opdeles i mindre, fokuserede kontekster for at begrænse omfanget af nye renderinger, og tilstand og afsendelse bør adskilles i to kontekster, så komponenter, der kun sender handlinger, aldrig renderes igen ved ændringer i tilstanden. Nu ser vi på useEffect-hooken og afhængighedsarrays til datahentning.
Lær JavaScript med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 30
- Lektioner
- 120
Ofte stillede spørgsmål
Er lektionen “Undgåelse af ydeevneproblemer med context” gratis?
Ja — alle 3 lektioner i læringssporet React Native Academy, inklusive “Undgåelse af ydeevneproblemer med context”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. React Native Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Undgåelse af ydeevneproblemer med context”?
Identificér unødvendige renders, der skyldes ændringer i context-værdier, opdel context i flere providere, og memoizér context-værdier for at optimere ydeevnen. Du øver dig i React Native Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på React Native Academy?
Der kræves ingen tidligere erfaring. React Native Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.
Hvor lang tid tager lektionen “Undgåelse af ydeevneproblemer med context”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne React Native Academy-lektion?
Ja. Alle React Native Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Oprettelse og levering af en context
- Brug af context med useContext
- En ThemeContext med mørk tilstand
- Undgåelse af ydeevneproblemer med context