React.Component vs React.PureComponent

224

Oficjalna React Dokumentów stanu, że „ React.PureComponent„s shouldComponentUpdate()tylko płytko porównuje obiektów”i odradza to jeśli stan jest«głęboko».

Biorąc to pod uwagę, czy jest jakiś powód, dla którego należy preferować React.PureComponenttworzenie komponentów React?

Pytania :

  • czy jest jakikolwiek wpływ na wydajność w użyciu, na React.Componentktóry możemy się zdecydować React.PureComponent?
  • Zgaduję, shouldComponentUpdate()że PureComponentwykonuje tylko płytkie porównania. Jeśli tak jest, czy nie można zastosować tej metody do głębszych porównań?
  • „Co więcej, React.PureComponent„s shouldComponentUpdate()przeskakuje prop aktualizacje dla całego komponentu poddrzewa”- Czy to znaczy, że zmiany prop są ignorowane?

Pytanie powstało z czytania na tym średnim blogu , jeśli to pomaga.

semuzaboi
źródło
5
Wiem, że minęło kilka miesięcy od opublikowania tego, ale pomyślałem, że ten artykuł może pomóc: 60devs.com/pure-component-in-react.html
MrOBrian

Odpowiedzi:

282

Główną różnicą pomiędzy React.PureComponenti React.Componentto PureComponentrobi porównanie płytkie o zmianie stanu. Oznacza to, że porównując wartości skalarne, porównuje ich wartości, ale porównując obiekty, porównuje tylko odniesienia. Pomaga poprawić wydajność aplikacji.

Powinieneś wybrać, React.PureComponentkiedy możesz spełnić którykolwiek z poniższych warunków.

  • Stan / Rekwizyty powinny być niezmiennym obiektem
  • Stan / Rekwizyty nie powinny mieć hierarchii
  • Powinieneś zadzwonić, forceUpdategdy zmienią się dane

Jeśli używasz React.PureComponent, upewnij się, że wszystkie elementy potomne są również czyste.

czy jest jakikolwiek wpływ na wydajność przy użyciu React.component, który możemy rozważyć wybierając React.PureComponent?

Tak, zwiększy to wydajność Twojej aplikacji (z powodu płytkiego porównania)

Zgaduję, że shouldComponentUpdate () Purecomponent wykonuje tylko płytkie porównania. Jeśli tak jest, to czy wspomnianej metody nie można zastosować do głębszych porównań?

Zgadłeś poprawnie. Możesz go użyć, jeśli spełnisz którykolwiek z wyżej wymienionych warunków.

„Ponadto funkcja React.PureComponent shouldComponentUpdate () pomija aktualizacje podpór dla całego poddrzewa komponentu” - Czy to oznacza, że ​​zmiany podpór są ignorowane?

Tak, zmiany rekwizytów zostaną zignorowane, jeśli nie znajdzie różnicy w płytkim porównaniu.

vimal1083
źródło
1
Cześć @VimalrajSankar. dzięki za pomoc tutaj. Czy możesz podać przykład następującego oświadczenia It means that when comparing scalar values it compares their values, but when comparing objects it compares only references. It helps to improve the performance of the app.:? Dzięki
Ishan Patel,
1
@ Mr.Script Mam nadzieję, że to pomoże stackoverflow.com/a/957602/2557900
vimal1083
3
State/Props should not have a hierarchyprzepraszam, czy możesz trochę wyjaśnić, co oznacza tutaj hierarchia?
Sany Liew
1
@SanyLiew oznacza stan i rekwizyty powinny zawierać tylko prymitywne wartości, takie jak liczby i łańcuchy, ale nie obiekty w obiektach (hierarchia).
jedmao
3
jeśli stan / rekwizyty to obiekt niezmienny, to powinno być w porządku mieć hierarchię i nadal używać PureComponent, o ile hierarchia ta utrzymuje również obiekt niezmienny, prawda?
Sany Liew
38

Componenti PureComponentmają jedną różnicę

PureComponentjest dokładnie taki sam, Componentz wyjątkiem tego, że obsługuje tę shouldComponentUpdatemetodę.

Gdy rekwizyty lub zmiany stanu PureComponentdokonają płytkiego porównania zarówno rekwizytów, jak i stanu. Componentz drugiej strony nie porówna aktualnych rekwizytów i stanu z kolejnymi po wyjęciu z pudełka. W związku z tym komponent będzie renderował się ponownie przy każdym shouldComponentUpdatewywołaniu.

Płytkie porównanie

Porównując poprzednie rekwizyty i stan do następnego, płytkie porównanie sprawdzi, czy prymitywy mają tę samą wartość (np. 1 równa się 1 lub czy prawda równa się prawdzie) i czy odwołania są takie same między bardziej złożonymi wartościami javascript, takimi jak obiekty i tablice.

Źródło: https://codeburst.io/when-to-use-component-or-purecomponent-a60cfad01a81

Bashirpour
źródło
React.Component => więc jeśli ponownie renderuję ten sam komponent z tymi samymi rekwizytami kilka razy. uruchomi to renderowanie dziecka. bez względu na to, czy rekwizyty się zmieniły, czy nie
Ehsan sarshar
23

Główną różnicą, jak widzę, jest to, że składnik ponownie się wysyła za każdym razem, gdy jego rodzic ponownie się wysyła, niezależnie od tego, czy rekwizyty i stan składnika uległy zmianie.

Z drugiej strony, czysty komponent nie zrenderuje się, jeśli jego rodzic zrenderuje, chyba że rekwizyty (lub stan) czystego komponentu ulegną zmianie.

Załóżmy na przykład, że mamy drzewo komponentów z trzypoziomową hierarchią: rodzic, dzieci i wnuki.

Gdy rekwizyty rodzica zostaną zmienione w taki sposób, że rekwizyty tylko jednego dziecka zostaną zmienione, wówczas:

  • jeśli wszystkie komponenty są zwykłymi komponentami, całe drzewo komponentów zrenderuje się
  • jeśli wszystkie dzieci i wnuki są czystymi składnikami, tylko jedno dziecko się podda i jedno lub wszystkie jego wnuki, w zależności od tego, czy ich rekwizyty zostaną zmienione. Jeśli w tym drzewie komponentów znajduje się wiele komponentów, może to oznaczać znaczny wzrost wydajności.

Czasami jednak stosowanie czystych składników nie będzie miało żadnego wpływu. Miałem taki przypadek, gdy rodzic otrzymał rekwizyty ze sklepu redux i musiałem przeprowadzić skomplikowane obliczenia rekwizytów dla dzieci. Rodzic użył płaskiej listy do renderowania swoich dzieci.

W rezultacie za każdym razem, gdy nastąpiła nawet niewielka zmiana w magazynie redux, cała tablica z płaską listą danych dla dzieci była ponownie obliczana. Oznaczało to, że dla każdego komponentu drzewa rekwizyty były nowymi obiektami, nawet jeśli wartości się nie zmieniały.

W takim przypadku czyste komponenty nie pomagają, a wzrost wydajności można osiągnąć tylko przy użyciu zwykłych komponentów i sprawdzania w elementach potomnych, w shouldComponentUpdate, jeśli konieczne jest ponowne wyrenderowanie.

Yossi
źródło