You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/docs/reconciliation.md
+13-13Lines changed: 13 additions & 13 deletions
Original file line number
Diff line number
Diff line change
@@ -4,11 +4,11 @@ title: Rekoncyliacja
4
4
permalink: docs/reconciliation.html
5
5
---
6
6
7
-
Deklaratywne API Reacta sprawia, że nie musisz się martwić co dokładnie zmienia się przy każdej aktualizacji. Dzięki temu pisanie aplikacji staje sie dużo prostsze, jednak dokładna implementacja nie jest oczywista. W tym artykule wyjaśniamy decyzje które podjęliśmy przy projektowaniu algorytmu różnicującego w Reakcie, mające zapewnić przewidywalność aktualizacji komponentów przy zachowaniu wysokiej wydajności.
7
+
Deklaratywność API Reacta sprawia, że nie musisz się martwić co dokładnie zmienia się przy każdej aktualizacji, dzięki czemu pisanie aplikacji staje się dużo prostsze. Dokładna implementacja nie jest jednak tak oczywista. W tym artykule wyjaśniamy decyzje, które podjęliśmy przy projektowaniu algorytmu różnicującego w Reakcie, mając na celu zapewnienie przewidywalności aktualizacji komponentów przy zachowaniu wysokiej wydajności.
8
8
9
9
## Motywacja {#motivation}
10
10
11
-
Podczas korzystania z Reacta, w danym momencie możesz potraktować funkcję `render()` jako tworzącą drzewo elementów Reacta. Podczas następnej zmiany stanu, bądź aktualizacji właściwości funkcja `render()` zwróci inne drzewo elementów React. Zadaniem Reacta jest wtedy opracować wydajny sposób na aktualizację UI tak by dopasować je do najświeższego drzewa elementów.
11
+
Podczas korzystania z Reacta, w danym momencie możesz potraktować funkcję `render()` jako tworzącą drzewo elementów Reacta. Podczas następnej zmiany stanu bądź aktualizacji właściwości funkcja `render()` zwróci inne drzewo elementów React. Zadaniem Reacta jest wtedy opracować wydajny sposób na aktualizację UI, tak by dopasować je do najświeższego drzewa elementów.
12
12
13
13
Istnieją ogólne rozwiązania algorytmicznego problemu generowania najmniejszej liczby operacji wymaganych do przekształcenia drzew elementów. Jednakże nawet [najlepsze znane algorytmy](https://grfia.dlsi.ua.es/ml/algorithms/references/editsurvey_bille.pdf) mają złożoność rzędu O(n<sup>3</sup>) gdzie n jest liczbą elementów w drzewie.
14
14
@@ -25,7 +25,7 @@ Podczas różnicowania dwóch drzew React najpierw porównuje elementy nadrzędn
25
25
26
26
### Elementy różnych typów {#elements-of-different-types}
27
27
28
-
Zawsze gdy elementy nadrzędne różnią się typem React pozbywa się starego drzewa i buduje nowe od podstaw. Zamiana `<a>` na `<img>`, czy `<Article>` na `<Comment>`, lub `<Button>` na `<div>` - każda z tych zmian spowoduje całkowite przebudowanie drzewa.
28
+
Zawsze, gdy elementy nadrzędne różnią się typem React pozbywa się starego drzewa i buduje nowe od podstaw. Zamiana `<a>` na `<img>`, czy `<Article>` na `<Comment>`, lub `<Button>` na `<div>` - każda z tych zmian spowoduje całkowite przebudowanie drzewa.
29
29
30
30
Gdy React pozbywa się starego drzewa, wszystkie przypisane do niego węzły DOM są niszczone. W instancjach komponentów wywoływane jest `componentWillUnmount()`. Podczas budowania nowego drzewa do DOMu dodawane są nowe węzły. W instancjach komponentów wywoływane jest `UNSAFE_componentWillMount()` a następnie `componentDidMount()`. Jakikolwiek stan przypisany do starego drzewa jest bezpowrotnie stracony.
31
31
@@ -61,21 +61,21 @@ Na przykład:
61
61
62
62
Porównując te dwa elementy, React wie by zmienić jedynie `className` na dostępnym węźle DOMu.
63
63
64
-
Aktualizując `style`, React wie również by aktualizować jedynie te właściwości, które uległy zmianie. Na przykład:
64
+
Aktualizując `style`, React wie również, by aktualizować jedynie te właściwości, które uległy zmianie. Na przykład:
Przy aktualizacji tych elementów React wie by zmodyfikować jedynie `color`, a nie również `fontWeight`.
72
+
Przy aktualizacji tych elementów React wie, by zmodyfikować jedynie `color`, a nie również `fontWeight`.
73
73
74
74
Po obsłużeniu danego węzła DOMu React rekursywnie wywołuje algorytm na kolejnych potomkach w drzewie.
75
75
76
76
### Komponenty tego samego typu {#component-elements-of-the-same-type}
77
77
78
-
Gdy komponent jest aktualizowany, jego instacja pozostaje bez zmian dzięki czemu stan jest zachowany pomiędzy kolejnymi renderami. React aktualizuje właściwości instancji zgodnie z nowym elementem i wywołuje na niej `UNSAFE_componentWillReceiveProps()`, `UNSAFE_componentWillUpdate()` oraz `componentDidUpdate()`.
78
+
Gdy komponent jest aktualizowany, jego instancja pozostaje bez zmian, dzięki czemu stan jest zachowany pomiędzy kolejnymi renderami. React aktualizuje właściwości instancji zgodnie z nowym elementem i wywołuje na niej `UNSAFE_componentWillReceiveProps()`, `UNSAFE_componentWillUpdate()` oraz `componentDidUpdate()`.
79
79
80
80
Następnie wywołana zostaje metoda `render()`, a algorytm różnicujący sięga dalej w głąb drzewa.
81
81
@@ -148,21 +148,21 @@ Dobranie stosownego klucza zazwyczaj nie nastręcza trudności. Element, który
148
148
<li key={item.id}>{item.name}</li>
149
149
```
150
150
151
-
W innym przypadku, można dodać nowe id do modelu danych, bądź wykorzystać funkcję skrótu (ang. *hash function*) do wygenerowania klucza. Klucz musi być unikalny jedynie względem swego rodzeństwa.
151
+
W przeciwnym wypadku można dodać nowe id do modelu danych, bądź wykorzystać funkcję skrótu (ang. *hash function*) do wygenerowania klucza. Klucz musi być unikalny jedynie względem swego rodzeństwa.
152
152
153
-
W ostatecznym wypadku jako klucza można użyć indeksu elementu w tablicy. Rozwiązanie to sprawdzi się jeśli kolejność elementów w tablicy jest stała, w przypadku zmiennej kolejności różnicowanie będzie mniej wydajne.
153
+
W ostateczności jako klucza można użyć indeksu elementu w tablicy. Rozwiązanie to sprawdzi się jeśli kolejność elementów w tablicy jest stała, w przypadku zmiennej kolejności różnicowanie będzie mniej wydajne.
154
154
155
-
W przypadku użycia indeksu jako klucza, zmiany w kolejności elementów tablicy mogą również powodować problemy z stanem komponentów. Instancje komponentów są aktualizowane bądź zatrzymywane w oparciu o klucz. Jeśli klucz jest indeksem, każda zmiana pozycji elementu w tablicy powoduje zmianę klucza. W rezultacie stan komponentów może zostać zaktualizowany w nieprzewidywalny sposób i powodować trudne do zidentyfikowania błędy.
155
+
W przypadku użycia indeksu jako klucza, zmiany w kolejności elementów tablicy mogą również powodować problemy ze stanem komponentów. Instancje komponentów są aktualizowane bądź nie, na podstawie klucza. Jeśli klucz jest indeksem, każda zmiana pozycji elementu w tablicy powoduje zmianę klucza. W rezultacie stan komponentów może zostać zaktualizowany w nieprzewidywalny sposób i powodować trudne do zidentyfikowania błędy.
156
156
157
-
Na podanym CodePenie można zapoznać się z [przykładowym problemem jaki stwarza stosowanie indeksów jako kluczy](codepen://reconciliation/index-used-as-key), a z kolei tutaj pokazany jest [sposób w jaki unikanie indeksów w kluczu rozwiązuje problemy z wstawianiem, sortowaniem oraz zmianą pozycji elementów](codepen://reconciliation/no-index-used-as-key).
157
+
Na podanym CodePenie można zapoznać się z [przykładowym problemem, jaki stwarza stosowanie indeksów jako kluczy](codepen://reconciliation/index-used-as-key), a z kolei tutaj pokazany jest [sposób, w jaki unikanie indeksów w kluczu rozwiązuje problemy z wstawianiem, sortowaniem oraz zmianą pozycji elementów](codepen://reconciliation/no-index-used-as-key).
158
158
159
159
## Kompromisy {#tradeoffs}
160
160
161
-
Należy pamiętać, że algorytm rekoncyliacji to szczegół implementacyjny. React mógły rerenderować całą aplikację przy każdej akcji; rezultat byłby ten sam.
162
-
Dla jasności, przez rerender w tym kontekście rozumiemy wywołanie `render` dla wszystkich komponentów, nie oznacza to że zostaną one odmontowane i zamontowane ponownie.
161
+
Należy pamiętać, że algorytm rekoncyliacji to szczegół implementacyjny. React mógłby rerenderować całą aplikację przy każdej akcji; rezultat byłby ten sam.
162
+
Dla jasności, przez rerender w tym kontekście rozumiemy wywołanie `render` dla wszystkich komponentów, nie oznacza to, że zostaną one odmontowane i zamontowane ponownie.
163
163
Oznacza jedynie zaaplikowanie zmian według reguł, które dotychczas przedstawiliśmy.
164
164
165
-
Regularnie usprawniamy algorytm heurystyczny by zoptymalizować wydajność w najczęstszych przypadkach. W aktualnej implementacji możemy wyrazić fakt, iż poddrzewo zmieniło pozycję względem rodzeństwa, nie jesteśmy jednak w stanie wskazać, że zostało bez zmian przeniesione gdzie indziej. Algorytm wymusi rerender całego poddrzewa.
165
+
Regularnie usprawniamy algorytm heurystyczny, by zoptymalizować wydajność w najczęstszych przypadkach. W aktualnej implementacji możemy wyrazić fakt, iż poddrzewo zmieniło pozycję względem rodzeństwa, nie jesteśmy jednak w stanie wskazać, że zostało bez zmian przeniesione gdzie indziej. Algorytm wymusi rerender całego poddrzewa.
166
166
167
167
Ponieważ React opiera się na heurystyce, tracimy na wydajności zawsze gdy nie spełniamy jej założeń.
0 commit comments