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
-[Подход 1: «Получаемпослерендера» (задержка не используется)](#approach-1-fetch-on-render-not-using-suspense)
47
+
-[Подход 2: «Получаемпотомрендерим» (задержка не используется)](#approach-2-fetch-then-render-not-using-suspense)
48
+
-[Подход 3: «Рендерим во времяполученияданных» (используем Задержку)](#approach-3-render-as-you-fetch-using-suspense)
49
49
-[Начинаем получать данные рано](#start-fetching-early)
50
50
-[Мы все ещё в этом разбираемся](#were-still-figuring-this-out)
51
51
-[Задержка и состояние гонки](#suspense-and-race-conditions)
@@ -149,17 +149,17 @@ function ProfileTimeline() {
149
149
150
150
Наоборот, мы взглянем на Задержку, как на следующий логический шаг в перечне подходов:
151
151
152
-
***Получаем-после-рендера (например, `fetch` в `useEffect`):** Начинаем рендерить компоненты. Каждый из этих компонентов может вызвать получение данных в своих «эффектах» и методах жизненного цикла. Этот подход обычно ведёт к «водопадам».
153
-
***Получаем-потом-рендерим (например, Relay без Задержки):** Начинаем получать все данные для следующего экрана как можно раньше. Когда данные готовы – рендерим новый экран. Мы ничего не можем делать пока не получим все данные.
154
-
***Рендерим-во-время-получения-данных (например, Relay с Задержкой):** Начинаем получать все требуемые данные для следующего экрана как можно раньше и начинаем рендерить новый экран *немедленно — до того, как получим ответ от сети*. По мере поступления данных, React повторяет рендер компонентов, которым всё ещё нужны данные, до тех пор, пока они не будут готовы.
152
+
***«Получаемпослерендера» (например, `fetch` в `useEffect`):** Начинаем рендерить компоненты. Каждый из этих компонентов может вызвать получение данных в своих «эффектах» и методах жизненного цикла. Этот подход обычно ведёт к «водопадам».
153
+
***«Получаемпотомрендерим» (например, Relay без Задержки):** Начинаем получать все данные для следующего экрана как можно раньше. Когда данные готовы – рендерим новый экран. Мы ничего не можем делать пока не получим все данные.
154
+
***«Рендерим во времяполученияданных» (например, Relay с Задержкой):** Начинаем получать все требуемые данные для следующего экрана как можно раньше и начинаем рендерить новый экран *немедленно — до того, как получим ответ от сети*. По мере поступления данных, React повторяет рендер компонентов, которым всё ещё нужны данные, до тех пор, пока они не будут готовы.
155
155
156
156
>Примечание
157
157
>
158
158
>Это немного упрощено и на практике требуется использование нескольких подходов. Тем не менее, мы будем рассматривать их отдельно, чтобы лучше отразить компромиссы, которые они требуют.
159
159
160
160
Для сравнения подходов мы реализуем страницу с профилем пользователя используя каждый из них.
161
161
162
-
### Подход 1: Получаем-после-рендера (задержка не используется) {#approach-1-fetch-on-render-not-using-suspense}
162
+
### Подход 1: «Получаемпослерендера» (задержка не используется) {#approach-1-fetch-on-render-not-using-suspense}
163
163
164
164
Распространённый сегодня способ получения данных в React с использованием эффекта:
165
165
@@ -175,7 +175,7 @@ componentDidMount() {
175
175
}
176
176
```
177
177
178
-
Мы зовем этот подход «получаем-после-рендера» потому что получение данных начинается *после* рендера компонента на экране. Это приводит к проблеме, известной как «водопад».
178
+
Мы зовем этот подход «получаемпослерендера» потому что получение данных начинается *после* рендера компонента на экране. Это приводит к проблеме, известной как «водопад».
179
179
180
180
Взгляните на компоненты `<ProfilePage>` и `<ProfileTimeline>`:
181
181
@@ -233,7 +233,7 @@ function ProfileTimeline() {
233
233
234
234
Водопады распространены в коде который получает данные после рендера. Их можно устранить, но по мере роста продукта, многие люди предпочитают использовать решение, которое защищает от этой проблемы.
235
235
236
-
### Подход 2: Получаем-потом-рендерим (задержка не используется) {#approach-2-fetch-then-render-not-using-suspense}
236
+
### Подход 2: «Получаемпотомрендерим» (задержка не используется) {#approach-2-fetch-then-render-not-using-suspense}
237
237
238
238
Библиотеки могут предотвратить появление водопадов предлагая более централизованный способ получения данных. Например, Relay решает эту проблему перемещением информации о данных, которые нужны компоненту в статически анализируемые *фрагменты*, которые позже собираются в единый запрос.
239
239
@@ -307,7 +307,7 @@ function ProfileTimeline({ posts }) {
307
307
308
308
Конечно, это можно исправить в данном примере. Мы можем убрать вызов `Promise.all()` и ждать оба промиса отдельно. Однако этот подход прогрессивно усложняется с увеличением количества данных и ростом дерева компонентов. Сложно писать надежные компоненты когда произвольные части дерева данных могут исчезать или устаревать. Поэтому рендер *после* получения всех данных для нового экрана часто является более практичным вариантом.
309
309
310
-
### Подход 3: Рендерим-во-время-получения-данных (используем Задержку) {#approach-3-render-as-you-fetch-using-suspense}
310
+
### Подход 3: «Рендерим во времяполученияданных» (используем Задержку) {#approach-3-render-as-you-fetch-using-suspense}
311
311
312
312
В предыдущем подходе мы получали данные перед вызовом `setState`:
313
313
@@ -371,13 +371,13 @@ function ProfileTimeline() {
371
371
372
372
**Чем больше потоков данных поступает, React будет пробовать рендерить и каждый раз он сможет продвигаться «глубже».** Когда данные `resource.user` получены, компонент `<ProfileDetails>` успешно отрендерится и нам больше не потребуется заглушка `<h1>Loading profile...</h1>`. В итоге мы получим все данные и заглушек больше не будет на экране.
373
373
374
-
Здесь есть интересный момент. Даже если мы используем клиент GraphQL, который собирает все требования к данным в единый запрос, *потоковая передача ответа позволяет нам быстрее показать больше контента*. Так как мы рендерим *во время получения* (в отличии от *после* получения) и если `user` появится в ответе раньше, чем `posts`, мы сможем «убрать» внешнюю заглушку `<Suspense>` до окончания ответа. Мы могли упустить это ранее, но даже при подходе получаем-потом-рендерим решение содержит водопад: между получением и рендером. Задержка не страдает от этого водопада и библиотеки, такие как Relay пользуются этим.
374
+
Здесь есть интересный момент. Даже если мы используем клиент GraphQL, который собирает все требования к данным в единый запрос, *потоковая передача ответа позволяет нам быстрее показать больше контента*. Так как мы рендерим *во время получения* (в отличии от *после* получения) и если `user` появится в ответе раньше, чем `posts`, мы сможем «убрать» внешнюю заглушку `<Suspense>` до окончания ответа. Мы могли упустить это ранее, но даже при подходе «получаемпотомрендерим» решение содержит водопад: между получением и рендером. Задержка не страдает от этого водопада и библиотеки, такие как Relay пользуются этим.
375
375
376
376
Обратите внимание, как мы избавились от проверок `if (...)` «идет загрузка» в наших компонентах. Это не только убирает шаблонный код, но и упрощает быстрые изменения в дизайне. Например, если мы хотим, чтобы информация о пользователе и его сообщения всегда появлялись вместе, мы можем удалить разделение `<Suspense>` между ними. Или мы можем сделать их независимыми от друг друга, предоставив каждому *собственный* `<Suspense>`. Задержка позволяет нам изменить степень раздробленности наших состояний загрузки и управлять их последовательностью без больших изменений в коде.
377
377
378
378
## Начинаем получать данные рано {#start-fetching-early}
379
379
380
-
Если вы работает над библиотекой получения данных, есть важный аспект в подходе Рендерим-во-время-получения-данных, который не стоит упускать. **Мы запускаем получение данных _перед_ рендером.** Посмотрите внимательно на этот пример:
380
+
Если вы работает над библиотекой получения данных, есть важный аспект в подходе «рендерим во времяполученияданных», который не стоит упускать. **Мы запускаем получение данных _перед_ рендером.** Посмотрите внимательно на этот пример:
0 commit comments