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
+20-20Lines changed: 20 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,24 +8,24 @@ React предоставляет декларативный API, который
8
8
9
9
## Мотивация {#motivation}
10
10
11
-
При работе с React вы можете понимать `render()` как функцию, которая создаёт дерево React-элементов в какой-то момент времени. При последующем обновлении состояния или пропсов функция `render()`вернёт новое дерево React-элементов. Теперь React должен понять, как эффективно обновить UI, чтобы он совпадал с новейшим из деревьев.
11
+
При работе с React вы понимаете `render()` как функцию, которая создаёт дерево React-элементов в какой-то момент времени. При следующем обновлении состояния или пропсов функция `render()`возвращает новое дерево React-элементов. Во время выполнения этой функции React должен выяснить как наиболее эффективно обновить пользовательский интерфейс для соответствия новому дереву.
12
12
13
-
Существует несколько общих решений алгоритмической проблемы трансформации одного дерева в другое за минимальное количество операций. Тем не менее, [передовые алгоритмы](http://grfia.dlsi.ua.es/ml/algorithms/references/editsurvey_bille.pdf) имеют сложность порядка O(n<sup>3</sup>), где n — это число элементов в дереве.
13
+
Существует несколько общих решений алгоритмической проблемы трансформации одного дерева в другое за минимальное количество операций. Тем не менее, даже [передовые алгоритмы](http://grfia.dlsi.ua.es/ml/algorithms/references/editsurvey_bille.pdf) имеют сложность порядка O(n<sup>3</sup>), где n — это число элементов в дереве.
14
14
15
-
Если бы мы использовали это в React, отображение 1000 элементов потребовало бы порядка миллиарда сравнений. Это слишком дорого. Взамен, React реализует эвристический алгоритм O(n), который основывается на двух предположениях:
15
+
Если бы мы использовали это в React, отображение 1000 элементов потребовало бы порядка миллиарда сравнений. Это слишком дорого. Взамен, React реализует эвристический алгоритм O(n), который основывается на двух утверждениях:
16
16
17
17
1. Два элемента с разными типами произведут разные деревья.
18
-
2. Разработчик может указать, какие дочерние элементы могут оставаться стабильными между разными рендерами с помощью пропа `key`.
18
+
2. Разработчик может указать какие дочерние элементы останутся стабильными между рендерами с помощью пропа `key`.
19
19
20
-
На практике эти предположения верны почти во всех случаях.
20
+
На практике эти утверждения верны почти во всех случаях.
21
21
22
22
## Алгоритм сравнения {#the-diffing-algorithm}
23
23
24
-
При сравнении двух деревьев первым делом React сравнивает два корневых элемента. Поведение различается в зависимости от типов корневых элементов.
24
+
React сравнивает деревья начиная с их корневых элементов и направляется вниз. Сравниваются типы (теги) корневых элементов.
25
25
26
26
### Элементы различных типов {#elements-of-different-types}
27
27
28
-
Всякий раз, когда корневые элементы имеют различные типы, React уничтожает старое дерево и строит новое с нуля. Переходы от`<a>`к`<img>`, или от`<Article>`к`<Comment>`, или от`<Button>`к`<div>` приведут к полному перестроению.
28
+
сякий раз, когда корневые элементы имеют различные типы, React уничтожает старое дерево и строит новое с нуля. Трансформация из`<a>`в`<img>`, или из`<Article>`в`<Comment>`, или из`<Button>`в`<div>` приведут к полному перестроению вложенных элементов.
29
29
30
30
При уничтожении дерева старые DOM-узлы удаляются. Экземпляры компонента получают `componentWillUnmount()`. При построении нового дерева, новые DOM-узлы вставляются в DOM. Экземпляры компонента получают `UNSAFE_componentWillMount()`, а затем `componentDidMount()`. Любое состояние, связанное со старым деревом, теряется.
31
31
@@ -41,7 +41,7 @@ React предоставляет декларативный API, который
41
41
</span>
42
42
```
43
43
44
-
При этом старый `Counter` уничтожится, а новый — смонтируется.
44
+
При этом старый `Counter` уничтожится и смонтируется новый.
45
45
46
46
>Примечание:
47
47
>
@@ -59,7 +59,7 @@ React предоставляет декларативный API, который
59
59
<divclassName="after"title="stuff" />
60
60
```
61
61
62
-
Сравнивая эти элементы, React знает, что нужно модифицировать только `className` у лежащего в основе DOM-узла.
62
+
Сравнивая эти элементы, React знает, что нужно модифицировать только `className` у DOM-узла.
63
63
64
64
Обновляя `style`, React также знает, что нужно обновлять только изменившиеся свойства. Например:
65
65
@@ -69,9 +69,9 @@ React предоставляет декларативный API, который
69
69
<divstyle={{color:'green',fontWeight:'bold'}} />
70
70
```
71
71
72
-
При конвертации между этими элементами, React знает, что нужно модифицировать только стиль `color`, а `fontWeight` сохранить.
72
+
При конвертации между этими элементами, React знает, что нужно модифицировать только стиль `color`, не затронув `fontWeight`.
73
73
74
-
После обработки DOM-узла React рекурсивно проходится по дочерним элементам.
74
+
После обработки DOM-узла React рекурсивно проходит по дочерним элементам.
75
75
76
76
### Компоненты одного типа {#component-elements-of-the-same-type}
77
77
@@ -88,7 +88,7 @@ React предоставляет декларативный API, который
88
88
89
89
### Рекурсия по дочерним элементам {#recursing-on-children}
90
90
91
-
По умолчанию при рекурсивном обходе дочерних элементов DOM-узла React проходит по обоим спискам потомков одновременно и создаёт мутацию, когда находит отличие.
91
+
По умолчанию при рекурсивном обходе дочерних элементов DOM-узла React одновременно проходит по обоим спискам потомков и создаёт мутацию, когда находит отличие.
92
92
93
93
Например, при добавлении элемента в конец дочерних элементов, преобразование между этими деревьями работает отлично:
94
94
@@ -121,11 +121,11 @@ React сравнит два дерева `<li>первый</li>`, сравнит
121
121
<li>Москва</li>
122
122
</ul>
123
123
```
124
-
React будет мутировать каждого потомка, вместо того чтобы оставить `<li>Санкт-Петербург</li>` и `<li>Москва</li>` нетронутыми. Эта неэффективность может стать проблемой.
124
+
React, вместо того чтобы оставить `<li>Санкт-Петербург</li>` и `<li>Москва</li>` нетронутыми, будет мутировать каждого потомка. Эта неэффективность может стать проблемой.
125
125
126
126
### Ключи {#keys}
127
127
128
-
Для решения этой проблемы React поддерживает атрибут `key`. Когда у дочерних элементов есть ключи, React использует их, чтобы сопоставить потомков исходного дерева с потомками последующего дерева. Например, если добавить `key` к неэффективному примеру выше, преобразование дерева станет эффективным:
128
+
Для решения этой проблемы React поддерживает атрибут `key`. Когда у дочерних элементов есть ключи, React воспользуется ими, чтобы сопоставить потомков исходного дерева с потомками последующего дерева. Например, если добавить `key` к неэффективному примеру выше, преобразование дерева станет эффективнее:
129
129
130
130
```html
131
131
<ul>
@@ -140,7 +140,7 @@ React будет мутировать каждого потомка, вмест
140
140
</ul>
141
141
```
142
142
143
-
Теперь React знает, что элемент с ключом `'2014'` — новый, а элементы с ключами `'2015'` и `'2016'`только что переместились.
143
+
Теперь React знает, что элемент с ключом `'2014'` — новый, а элементы с ключами `'2015'` и `'2016'` переместились.
144
144
145
145
На практике найти ключ обычно несложно. Элемент, который вы хотите отобразить, уже может иметь уникальный идентификатор, и ключ может быть взят из ваших данных:
146
146
@@ -152,18 +152,18 @@ React будет мутировать каждого потомка, вмест
152
152
153
153
В крайнем случае вы можете передать индекс элемента массива в качестве ключа. Это работает хорошо в случае, если элементы никогда не меняют порядок. Перестановки элементов вызывают замедление.
154
154
155
-
При использовании ключей перестановки так же могут вызывать проблемы с состоянием компонента. Экземпляры компонента обновляются и повторно используются на основе их ключей. Перемещение элемента изменяет его, если ключ является индексом. В результате состояние компонента для таких вещей, как неуправляемые `<input>`, может смешаться и обновиться неожиданным образом.
155
+
Вдобавок перестановки элементов могут вызвать проблемы с состоянием компонента, когда в качестве ключей используются индексы. Экземпляры компонента обновляются и повторно используются на основе своих ключей. Если ключ является индексом, то перемещение элемента изменяет его. В результате состояние компонента для таких элементов , как неуправляемые `<input>`, может смешаться и обновиться неожиданным образом.
156
156
157
157
На CodePen [есть примеры проблем, которые могут быть вызваны использованием индексов в качестве ключей](codepen://reconciliation/index-used-as-key), а также есть [обновлённая версия того же примера, которая показывает как решаются проблемы с перестановкой, сортировкой и вставкой элементов в начало, если не использовать индексы как ключи](codepen://reconciliation/no-index-used-as-key).
158
158
159
159
## Компромиссы {#tradeoffs}
160
160
161
-
Важно помнить, что алгоритм согласования — это деталь реализации. React может повторно рендерить всё приложение на каждое действие, конечный результат будет тем же. Для ясности, повторный рендер в этом контексте означает вызов функции `render` для всех компонентов, но это не означает, что React размонтирует и смонтирует их заново. Он применит различия только следуя правилам, которые были обозначены в предыдущих разделах.
161
+
Важно помнить, что алгоритм согласования — это деталь реализации. React может повторно рендерить всё приложение на каждое действие, конечный результат будет тем же. Для ясности, повторный рендер в этом контексте означает вызов функции `render` для всех компонентов, но это не означает, что React размонтирует и смонтирует их заново. Он лишь применит различия следуя правилам, которые были обозначены выше.
162
162
163
-
Мы регулярно совершенствуем эвристику, чтобы ускорить часто встречающиеся варианты использования. В текущей реализации вы можете выразить факт того, что поддерево сдвинулось среди его соседей, но вы не можете сказать, что оно сдвинулось куда-то в другое место. Алгоритм повторно отрендерит всё поддерево.
163
+
Мы регулярно совершенствуем эвристику, чтобы повысить производительность. В текущей реализации вы можете выразить факт того, что поддерево было перемещено среди своих соседей, но вы не можете сказать, что оно переместилось куда-то в другое место. Алгоритм повторно рендерит всё поддерево.
164
164
165
-
React полагается на эвристику, следовательно, если предположения, на которых она основана, не соблюдены, пострадает производительность.
165
+
React полагается на эвристику, следовательно, если утверждения, на которых она основана, не соблюдены, то пострадает производительность.
166
166
167
-
1. Алгоритм не будет пытаться сопоставить поддеревья компонентов разных типов. Если вы заметите за собой, что пытаетесь чередовать компоненты разных типов с очень схожим выводом, то желательно сделать их компонентами одного типа. На практике мы не выявили с этим проблем.
167
+
1. Алгоритм не будет пытаться сравнивать поддеревья компонентов разных типов. Если вы заметите за собой, что пытаетесь использовать компоненты разных типов с очень схожим выводом, то, вероятно, стоит их сделать компонентами одного типа. На практике мы не выявили с этим проблем.
168
168
169
169
2. Ключи должны быть стабильными, предсказуемыми и уникальными. Нестабильные ключи (например, произведённые с помощью `Math.random()`) вызовут необязательное пересоздание многих экземпляров компонента и DOM-узлов, что может вызывать ухудшение производительности и потерю состояния у дочерних компонентов.
0 commit comments