Skip to content

Commit 0bf6a11

Browse files
committed
Обновлено содержание reconcilation.md.
Применены изменения @revidovich. Слегка перефразированы некоторые предложения.
1 parent 894263f commit 0bf6a11

File tree

1 file changed

+20
-20
lines changed

1 file changed

+20
-20
lines changed

content/docs/reconciliation.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,24 @@ React предоставляет декларативный API, который
88

99
## Мотивация {#motivation}
1010

11-
При работе с React вы можете понимать `render()` как функцию, которая создаёт дерево React-элементов в какой-то момент времени. При последующем обновлении состояния или пропсов функция `render()` вернёт новое дерево React-элементов. Теперь React должен понять, как эффективно обновить UI, чтобы он совпадал с новейшим из деревьев.
11+
При работе с React вы понимаете `render()` как функцию, которая создаёт дерево React-элементов в какой-то момент времени. При следующем обновлении состояния или пропсов функция `render()` возвращает новое дерево React-элементов. Во время выполнения этой функции React должен выяснить как наиболее эффективно обновить пользовательский интерфейс для соответствия новому дереву.
1212

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 — это число элементов в дереве.
1414

15-
Если бы мы использовали это в React, отображение 1000 элементов потребовало бы порядка миллиарда сравнений. Это слишком дорого. Взамен, React реализует эвристический алгоритм O(n), который основывается на двух предположениях:
15+
Если бы мы использовали это в React, отображение 1000 элементов потребовало бы порядка миллиарда сравнений. Это слишком дорого. Взамен, React реализует эвристический алгоритм O(n), который основывается на двух утверждениях:
1616

1717
1. Два элемента с разными типами произведут разные деревья.
18-
2. Разработчик может указать, какие дочерние элементы могут оставаться стабильными между разными рендерами с помощью пропа `key`.
18+
2. Разработчик может указать какие дочерние элементы останутся стабильными между рендерами с помощью пропа `key`.
1919

20-
На практике эти предположения верны почти во всех случаях.
20+
На практике эти утверждения верны почти во всех случаях.
2121

2222
## Алгоритм сравнения {#the-diffing-algorithm}
2323

24-
При сравнении двух деревьев первым делом React сравнивает два корневых элемента. Поведение различается в зависимости от типов корневых элементов.
24+
React сравнивает деревья начиная с их корневых элементов и направляется вниз. Сравниваются типы (теги) корневых элементов.
2525

2626
### Элементы различных типов {#elements-of-different-types}
2727

28-
Всякий раз, когда корневые элементы имеют различные типы, React уничтожает старое дерево и строит новое с нуля. Переходы от `<a>` к `<img>`, или от `<Article>` к `<Comment>`, или от `<Button>` к `<div>` приведут к полному перестроению.
28+
сякий раз, когда корневые элементы имеют различные типы, React уничтожает старое дерево и строит новое с нуля. Трансформация из `<a>` в `<img>`, или из `<Article>` в `<Comment>`, или из `<Button>` в `<div>` приведут к полному перестроению вложенных элементов.
2929

3030
При уничтожении дерева старые DOM-узлы удаляются. Экземпляры компонента получают `componentWillUnmount()`. При построении нового дерева, новые DOM-узлы вставляются в DOM. Экземпляры компонента получают `UNSAFE_componentWillMount()`, а затем `componentDidMount()`. Любое состояние, связанное со старым деревом, теряется.
3131

@@ -41,7 +41,7 @@ React предоставляет декларативный API, который
4141
</span>
4242
```
4343

44-
При этом старый `Counter` уничтожится, а новый — смонтируется.
44+
При этом старый `Counter` уничтожится и смонтируется новый.
4545

4646
>Примечание:
4747
>
@@ -59,7 +59,7 @@ React предоставляет декларативный API, который
5959
<div className="after" title="stuff" />
6060
```
6161

62-
Сравнивая эти элементы, React знает, что нужно модифицировать только `className` у лежащего в основе DOM-узла.
62+
Сравнивая эти элементы, React знает, что нужно модифицировать только `className` у DOM-узла.
6363

6464
Обновляя `style`, React также знает, что нужно обновлять только изменившиеся свойства. Например:
6565

@@ -69,9 +69,9 @@ React предоставляет декларативный API, который
6969
<div style={{color: 'green', fontWeight: 'bold'}} />
7070
```
7171

72-
При конвертации между этими элементами, React знает, что нужно модифицировать только стиль `color`, а `fontWeight` сохранить.
72+
При конвертации между этими элементами, React знает, что нужно модифицировать только стиль `color`, не затронув `fontWeight`.
7373

74-
После обработки DOM-узла React рекурсивно проходится по дочерним элементам.
74+
После обработки DOM-узла React рекурсивно проходит по дочерним элементам.
7575

7676
### Компоненты одного типа {#component-elements-of-the-same-type}
7777

@@ -88,7 +88,7 @@ React предоставляет декларативный API, который
8888
8989
### Рекурсия по дочерним элементам {#recursing-on-children}
9090

91-
По умолчанию при рекурсивном обходе дочерних элементов DOM-узла React проходит по обоим спискам потомков одновременно и создаёт мутацию, когда находит отличие.
91+
По умолчанию при рекурсивном обходе дочерних элементов DOM-узла React одновременно проходит по обоим спискам потомков и создаёт мутацию, когда находит отличие.
9292

9393
Например, при добавлении элемента в конец дочерних элементов, преобразование между этими деревьями работает отлично:
9494

@@ -121,11 +121,11 @@ React сравнит два дерева `<li>первый</li>`, сравнит
121121
<li>Москва</li>
122122
</ul>
123123
```
124-
React будет мутировать каждого потомка, вместо того чтобы оставить `<li>Санкт-Петербург</li>`  и `<li>Москва</li>` нетронутыми. Эта неэффективность может стать проблемой.
124+
React, вместо того чтобы оставить `<li>Санкт-Петербург</li>`  и `<li>Москва</li>` нетронутыми, будет мутировать каждого потомка. Эта неэффективность может стать проблемой.
125125

126126
### Ключи {#keys}
127127

128-
Для решения этой проблемы React поддерживает атрибут `key`. Когда у дочерних элементов есть ключи, React использует их, чтобы сопоставить потомков исходного дерева с потомками последующего дерева. Например, если добавить `key` к неэффективному примеру выше, преобразование дерева станет эффективным:
128+
Для решения этой проблемы React поддерживает атрибут `key`. Когда у дочерних элементов есть ключи, React воспользуется ими, чтобы сопоставить потомков исходного дерева с потомками последующего дерева. Например, если добавить `key` к неэффективному примеру выше, преобразование дерева станет эффективнее:
129129

130130
```html
131131
<ul>
@@ -140,7 +140,7 @@ React будет мутировать каждого потомка, вмест
140140
</ul>
141141
```
142142

143-
Теперь React знает, что элемент с ключом `'2014'` — новый, а элементы с ключами `'2015'` и `'2016'` только что переместились.
143+
Теперь React знает, что элемент с ключом `'2014'` — новый, а элементы с ключами `'2015'` и `'2016'` переместились.
144144

145145
На практике найти ключ обычно несложно. Элемент, который вы хотите отобразить, уже может иметь уникальный идентификатор, и ключ может быть взят из ваших данных:
146146

@@ -152,18 +152,18 @@ React будет мутировать каждого потомка, вмест
152152

153153
В крайнем случае вы можете передать индекс элемента массива в качестве ключа. Это работает хорошо в случае, если элементы никогда не меняют порядок. Перестановки элементов вызывают замедление.
154154

155-
При использовании ключей перестановки так же могут вызывать проблемы с состоянием компонента. Экземпляры компонента обновляются и повторно используются на основе их ключей. Перемещение элемента изменяет его, если ключ является индексом. В результате состояние компонента для таких вещей, как неуправляемые `<input>`, может смешаться и обновиться неожиданным образом.
155+
Вдобавок перестановки элементов могут вызвать проблемы с состоянием компонента, когда в качестве ключей используются индексы. Экземпляры компонента обновляются и повторно используются на основе своих ключей. Если ключ является индексом, то перемещение элемента изменяет его. В результате состояние компонента для таких элементов , как неуправляемые `<input>`, может смешаться и обновиться неожиданным образом.
156156

157157
На CodePen [есть примеры проблем, которые могут быть вызваны использованием индексов в качестве ключей](codepen://reconciliation/index-used-as-key), а также есть [обновлённая версия того же примера, которая показывает как решаются проблемы с перестановкой, сортировкой и вставкой элементов в начало, если не использовать индексы как ключи](codepen://reconciliation/no-index-used-as-key).
158158

159159
## Компромиссы {#tradeoffs}
160160

161-
Важно помнить, что алгоритм согласования — это деталь реализации. React может повторно рендерить всё приложение на каждое действие, конечный результат будет тем же. Для ясности, повторный рендер в этом контексте означает вызов функции `render` для всех компонентов, но это не означает, что React размонтирует и смонтирует их заново. Он применит различия только следуя правилам, которые были обозначены в предыдущих разделах.
161+
Важно помнить, что алгоритм согласования — это деталь реализации. React может повторно рендерить всё приложение на каждое действие, конечный результат будет тем же. Для ясности, повторный рендер в этом контексте означает вызов функции `render` для всех компонентов, но это не означает, что React размонтирует и смонтирует их заново. Он лишь применит различия следуя правилам, которые были обозначены выше.
162162

163-
Мы регулярно совершенствуем эвристику, чтобы ускорить часто встречающиеся варианты использования. В текущей реализации вы можете выразить факт того, что поддерево сдвинулось среди его соседей, но вы не можете сказать, что оно сдвинулось куда-то в другое место. Алгоритм повторно отрендерит всё поддерево.
163+
Мы регулярно совершенствуем эвристику, чтобы повысить производительность. В текущей реализации вы можете выразить факт того, что поддерево было перемещено среди своих соседей, но вы не можете сказать, что оно переместилось куда-то в другое место. Алгоритм повторно рендерит всё поддерево.
164164

165-
React полагается на эвристику, следовательно, если предположения, на которых она основана, не соблюдены, пострадает производительность.
165+
React полагается на эвристику, следовательно, если утверждения, на которых она основана, не соблюдены, то пострадает производительность.
166166

167-
1. Алгоритм не будет пытаться сопоставить поддеревья компонентов разных типов. Если вы заметите за собой, что пытаетесь чередовать компоненты разных типов с очень схожим выводом, то желательно сделать их компонентами одного типа. На практике мы не выявили с этим проблем.
167+
1. Алгоритм не будет пытаться сравнивать поддеревья компонентов разных типов. Если вы заметите за собой, что пытаетесь использовать компоненты разных типов с очень схожим выводом, то, вероятно, стоит их сделать компонентами одного типа. На практике мы не выявили с этим проблем.
168168

169169
2. Ключи должны быть стабильными, предсказуемыми и уникальными. Нестабильные ключи (например, произведённые с помощью `Math.random()`) вызовут необязательное пересоздание многих экземпляров компонента и DOM-узлов, что может вызывать ухудшение производительности и потерю состояния у дочерних компонентов.

0 commit comments

Comments
 (0)