React Academy · Lekcja

Dzielenie kontekstów w celu ograniczenia ponownych renderowań

Oddzielanie często zmieniających się wartości od stabilnych przez umieszczenie ich w różnych kontekstach.

Lekcja 1 z 413 kroki

Dzielenie kontekstów w celu ograniczenia ponownych renderowań to bezpłatna lekcja React Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej React Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs React Academy zawiera 4 lekcji w sumie.

Witamy

W tej lekcji dowie się Pani/Pan, jak podzielić konteksty React na osobne providery, aby ograniczyć ponowne renderowanie, gdy zmienia się tylko część wartości kontekstu.

Problem ponownego renderowania w Context

Każdy komponent, który wywołuje useContext(MyCtx), renderuje się ponownie, gdy zmieni się DOWOLNA część wartości kontekstu — nawet jeśli używana przez niego część się nie zmieniła. Jeden duży kontekst może powodować wiele niepotrzebnych ponownych renderów.

Podział według częstotliwości aktualizacji

Należy oddzielić wartości, które często się zmieniają, od tych, które zmieniają się rzadko. Każdą grupę należy umieścić we własnym kontekście. Komponenty korzystające z kontekstu subskrybują tylko ten kontekst, którego potrzebują.
const ThemeCtx = createContext('light');
const UserCtx = createContext(null);
// theme changes rarely; user changes on login/logout — same frequency is fine
// but notifCount changes every second — split it out!

Oddzielne konteksty danych i dispatch

Popularny wzorzec polega na podzieleniu jednego kontekstu na kontekst danych stanu, który powoduje ponowne renderowanie przy każdej zmianie, oraz drugi kontekst funkcji dispatch/setter, które są stabilne i nigdy nie powodują ponownego renderowania korzystających z nich komponentów. Komponenty korzystające wyłącznie z dispatch nie renderują się ponownie przy zmianach danych.
const CountCtx = createContext(0);
const SetCountCtx = createContext(() => {});

function Provider({ children }) {
  const [count, setCount] = useState(0);
  return (
    <CountCtx.Provider value={count}>
      <SetCountCtx.Provider value={setCount}>
        {children}
      </SetCountCtx.Provider>
    </CountCtx.Provider>
  );
}

Memoizacja kontekstu dispatch

Settery z useState są stabilne, czyli mają tę samą referencję podczas każdego renderowania, dlatego wartość kontekstu dispatch się nie zmienia. Jeśli jednak oblicza Pani/Pan obiekt akcji, należy opakować go w useMemo.
const actions = useMemo(() => ({
  increment: () => setCount(c => c + 1),
  reset: () => setCount(0),
}), []); // stable — empty deps

Zagnieżdżone providery

Należy zagnieżdżać wiele providerów w drzewie komponentów. Komponenty korzystające z kontekstu powinny importować i używać tylko konkretnego kontekstu, którego potrzebują, aby ograniczyć zakres subskrypcji.
function App() {
  return (
    <AuthProvider>
      <ThemeProvider>
        <NotificationsProvider>
          <Router />
        </NotificationsProvider>
      </ThemeProvider>
    </AuthProvider>
  );
}

Profilowanie przed podziałem

Przed podzieleniem kontekstów należy zawsze wykonać profilowanie za pomocą React DevTools. Niepotrzebne ponowne renderowanie stanowi problem tylko wtedy, gdy jest kosztowne. Nie należy nadmiernie komplikować kontekstów, które renderują się ponownie szybko.

Kompromisy związane z podziałem kontekstów

Więcej kontekstów oznacza więcej providerów w drzewie komponentów. Zwiększa to obciążenie poznawcze. Konteksty należy dzielić tylko wtedy, gdy profilowanie wykaże problem z wydajnością, a nie na wszelki wypadek.

Połączenie z React.memo

Nawet przy użyciu jednego kontekstu opakowanie kosztownych komponentów potomnych w React.memo sprawia, że renderują się one ponownie tylko wtedy, gdy zmienią się ich propsy, a nie wtedy, gdy zmieni się kontekst. Może to być prostsza alternatywa dla podziału kontekstów.
const ExpensiveChild = React.memo(function({ label }) {
  return <div>{label}</div>;
}); // won't re-render on context change if label hasn't changed

useReducer + Context

useReducer w połączeniu z kontekstem pozwala zarządzać złożonym stanem. Stan należy przechowywać w jednym kontekście, a funkcję dispatch w drugim. Dispatch jest stabilny, natomiast stan aktualizuje się przy każdej akcji.

Szybkie sprawdzenie

Dlaczego podzielenie stanu i dispatch na oddzielne konteksty poprawia wydajność?

Podsumowanie

Konteksty należy dzielić według częstotliwości aktualizacji: często zmieniający się stan umieszczać w jednym kontekście, a stabilne funkcje dispatch/setter w drugim. Najpierw należy wykonać profilowanie, dzielić konteksty tylko wtedy, gdy ma to znaczenie, i rozważyć React.memo jako prostszą alternatywę.

Następny temat

Następna lekcja: **Memoizacja wartości kontekstu za pomocą useMemo** — obiekty wartości kontekstu zostaną opakowane w useMemo, aby komponenty korzystające z kontekstu nie renderowały się ponownie przy niezmienionych danych.
Bezpłatny start

Ucz się React dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
88
Lekcje
324

Często zadawane pytania

Czy lekcja „Dzielenie kontekstów w celu ograniczenia ponownych renderowań” jest bezpłatna?

Tak — pełny tekst „Dzielenie kontekstów w celu ograniczenia ponownych renderowań” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu React Academy, przejdź na CoddyKit PRO. Kurs React Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Dzielenie kontekstów w celu ograniczenia ponownych renderowań”?

Oddzielanie często zmieniających się wartości od stabilnych przez umieszczenie ich w różnych kontekstach. Ćwiczysz React Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć React Academy?

Nie wymagamy żadnego doświadczenia. React Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Dzielenie kontekstów w celu ograniczenia ponownych renderowań”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji React Academy?

Tak. Każda lekcja React Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Dzielenie kontekstów w celu ograniczenia ponownych renderowań
  2. Zapamiętywanie wartości kontekstu za pomocą useMemo
  3. Wzorzec selektora kontekstu
  4. Kiedy nie używać kontekstu
← Powrót do React Academy