React memo, useMemo i useCallback (oraz ref, portale i useId)

React memo, useMemo, useCallback, forwardRef, portale i useId

React memo vs useMemo vs useCallback, forwardRef, portale, useId | We.Inc

Kiedy używać React memo, useMemo i useCallback, z licznikami renderów na żywo. Do tego forwardRef i ref jako prop w React 19, modale z createPortal, etykiety z useId i wirtualna lista na 10,000 wierszy.

Opakuj komponent w memo, aby pominąć rendery, gdy jego propsy się nie zmieniły. Użyj useCallback, aby funkcja przekazywana jako prop była ta sama między renderami, a useMemo, aby zapamiętać obiekt lub kosztowne obliczenie. Mają znaczenie tylko w połączeniu z memo lub przy realnym koszcie. Najpierw zmierz za pomocą React Profiler; liczniki na żywo poniżej pokazują różnicę.

Jedna linia na każde

Dema liczą prawdziwe rendery w Twojej przeglądarce. Wpisuj tekst w każde pole z wyłączonym i włączonym przełącznikiem i obserwuj liczniki. Druga połowa omawia API referencyjne, które pojawiają się obok pracy nad wydajnością: ref, portale i id.

Najczęściej zadawane pytania

Czym różni się useMemo od useCallback?

useMemo wywołuje Twoją funkcję i zapamiętuje zwracaną przez nią wartość. useCallback zapamiętuje samą funkcję. useCallback(fn, deps) to to samo co useMemo(() => fn, deps).

Czy powinienem opakować każdy komponent w memo?

Nie. Porównywanie propsów też kosztuje czas, a większość renderów jest tania. Używaj memo tam, gdzie Profiler pokazuje komponent renderujący się często z tymi samymi propsami i zajmujący zauważalny czas.

Czy forwardRef jest przestarzały?

W React 19 komponenty funkcyjne przyjmują ref jako zwykły prop, więc nowy kod nie potrzebuje forwardRef. Nadal działa, a zespół React zapowiedział, że zostanie oznaczony jako przestarzały w przyszłym wydaniu.

Po co używać portalu dla modala?

Modal wewnątrz karty z overflow hidden lub transformacją może zostać przycięty albo znaleźć się pod inną treścią. Renderowanie go do document.body za pomocą createPortal unika obu problemów, a modal nadal pozostaje w Twoim drzewie React.

Czy mogę używać useId jako kluczy listy?

Nie. useId służy do atrybutów dostępności, takich jak htmlFor i aria-describedby. Klucze powinny pochodzić z Twoich danych, na przykład z id w bazie danych.

Jak mierzyć

Częste błędy

Tabela decyzyjna: memo, useMemo, useCallback czy coś innego

Które narzędzie na który problem

Liczba renderów przed i po

memo: pomijanie renderów, gdy propsy są równe

Wpisz coś w pole. Bez memo lista przerenderowuje się przy każdym klawiszu, choć jej propsy się nie zmieniły. Z memo renderuje się raz.

useCallback: ta sama funkcja

Przekazanie funkcji strzałkowej inline psuje memo, ponieważ przy każdym renderze tworzona jest nowa funkcja. useCallback zwraca tę samą, dopóki nie zmienią się jej zależności.

useMemo: zapamiętanie kosztownego obliczenia

Filtrowanie 20,000 produktów przy każdym renderze to zmarnowana praca, gdy zmieniła się tylko niezwiązana wartość. useMemo uruchamia filtr ponownie tylko wtedy, gdy zmienią się products lub query.

forwardRef, ref jako prop, portale i useId

forwardRef (React 18 i wcześniejsze)

Rodzic nie może przekazać ref do komponentu funkcyjnego, chyba że komponent go przekaże dalej. forwardRef przekazuje ref do prawdziwego elementu.

ref jako prop (React 19)

Od React 19 komponenty funkcyjne otrzymują ref jak każdy inny prop, więc w nowym kodzie forwardRef nie jest już potrzebny.

createPortal dla modali i podpowiedzi

Portal renderuje children do innego węzła DOM, zwykle document.body, więc modal wydostaje się z rodziców z overflow hidden lub niskim z-index. Zdarzenia React nadal propagują się przez drzewo React.

useId dla par etykieta i pole

useId daje unikalne id, które zgadza się między renderem na serwerze i w przeglądarce, więc kilka kopii tego samego komponentu pola nigdy ze sobą nie koliduje.

Długie listy

react-window: lista 10,000 wierszy

List renderuje tylko widoczne wiersze plus kilka dodatkowych. Każdy wiersz dostaje index i style; style pozycjonuje wiersz i musi zostać zastosowany. Demo obok używa tego samego pomysłu, napisanego ręcznie.

Budujesz formularze? useId dobrze współgra z

React Hook Form

Lista wyrenderowana {n} razy (elementy: {count})

Opakuj listę w memo

Pisz tutaj

(rendery: {n})

Użyj useCallback

Mały

Średni

Duży

Wybrano: {x}

Zapamiętaj przez useMemo

Filtruj produkty

Niezwiązane kliknięcie ({n})

Pasuje {matches} z 20,000. Filtr uruchomiono {runs} razy; ostatnie uruchomienie trwało {ms} ms.

Szukaj

Ustaw fokus na wyszukiwaniu

To pole ma overflow hidden, a mimo to modal zakrywa całe okno.

Otwórz modal

Demo portalu

Zostałem wyrenderowany do document.body za pomocą createPortal.

Zamknij

E-mail

Odpowiadamy w ciągu jednego dnia.

E-mail (ponownie)

Ten sam komponent, inne id.

10,000 klientów

Klient {n}

10,000 wierszy, ale w DOM jest teraz tylko {n}.

Zacznij za darmo · Bez karty kredytowej

Powiązane: Poradniki

Produkt

Dla kogo

Funkcje

Zasoby

Firma

Mapa strony