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
Обновляя состояние, мы обычно ожидаем сразу же увидеть изменения на экране. В этом есть смысл, ведь мы хотим, чтобы наше приложение было отзывчивым к действиям пользователя. Тем не менее, существуют сценарии, при которых предпочтительно **отложить появление обновления на экране**.
27
27
28
28
Например, если мы переходим с одной страницы на другую, и часть кода или данных для следующего экрана ещё не загружена, может быть странным сразу увидеть пустую страницу с индикатором загрузки.
29
-
Скорее всего мы захотим задержаться на предыдущем экране. Реализация такого паттерна всегда была достаточно сложной в React. Конкурентный режим предоставляет новый набор интсрументов для решения таких задач.
29
+
Скорее всего мы захотим задержаться на предыдущем экране. Реализация такого паттерна всегда была достаточно сложной в React. Конкурентный режим предоставляет новый набор инструментов для решения таких задач.
30
30
31
31
-[Переходы](#transitions)
32
32
-[Wrapping setState in a Transition](#wrapping-setstate-in-a-transition)
Давайте вернёмся к [примеру](https://codesandbox.io/s/infallible-feather-xjtbu) с предыдущей страницы про [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html).
54
54
55
-
Когда мы нажимаем на кнопку "Next", чтобы переключить активный профиль, данные текущей страницы моментально пропадают и мы видим индикатор загрузки для всей страницы снова. Мы можем сказать, что это "нежелательное" состояние загрузки. **Было бы хорошо, если бы мы могли "пропустить" его и подождать пока загрузится конент перед переходом на новый экран**
55
+
Когда мы нажимаем на кнопку "Next", чтобы переключить активный профиль, данные текущей страницы моментально пропадают и мы видим индикатор загрузки для всей страницы снова. Мы можем сказать, что это "нежелательное" состояние загрузки. **Было бы хорошо, если бы мы могли "пропустить" его и подождать пока загрузится контент перед переходом на новый экран**
56
56
57
57
React предлагает новый встроенный хук `useTransition()`, чтобы решить эту задачу.
58
58
59
59
Чтобы его использовать, нам нужно выполнить три шага.
60
60
61
-
Во-первых, мы убедимся, что мы включили конкурентный режим. Мы поговорим подбробнее о [внедрении конекурентного режима](/docs/concurrent-mode-adoption.html) позже, но пока отметим, что необходимо использовать `ReactDOM.createRoot()` вместо `ReactDOM.render()` для того, чтобы воспользоваться этим решением:
61
+
Во-первых, мы убедимся, что мы включили конкурентный режим. Мы поговорим подробнее о [внедрении конкурентного режима](/docs/concurrent-mode-adoption.html) позже, но пока отметим, что необходимо использовать `ReactDOM.createRoot()` вместо `ReactDOM.render()` для того, чтобы воспользоваться этим решением:
62
62
63
63
```js
64
64
constrootElement=document.getElementById("root");
@@ -83,16 +83,16 @@ function App() {
83
83
// ...
84
84
```
85
85
86
-
**Сам по себе, этот код пока ничего не делает.** Для того чтобы настроить переходы состояния, нам нужно использовать возращаемое значение данного хука. Результатом вызова `useTransition` будут два значения:
86
+
**Сам по себе, этот код пока ничего не делает.** Для того чтобы настроить переходы состояния, нам нужно использовать возвращаемое значение данного хука. Результатом вызова `useTransition` будут два значения:
87
87
88
-
*`startTransition` является функцией. Мы будем использовать её для того чтобы сказать React *какое* обновление состояения мы хотим отложить.
88
+
*`startTransition` является функцией. Мы будем использовать её для того чтобы сказать React *какое* обновление состояния мы хотим отложить.
89
89
*`isPending` представляет собой булево значение. Через него React сообщает нам происходит переход в данный момент или нет.
90
90
91
91
**By itself, this code doesn't do anything yet.** We will need to use this Hook's return values to set up our state transition. There are two values returned from `useTransition`:
92
92
93
93
Мы будем использовать их в примере ниже.
94
94
95
-
Заметьте, мы передали в `useTransition` объект с конфигурацией. Это свойство `timeoutMs`, которое определяет **как долго мы готовы подождить пока переход закончится**. Передавая `{timeoutMs: 3000}`, мы говорим "Если следующий профиль будет загружаться более 3 секунд, покажи большой спиннер -- но до истечения этого таймаута можно показывать предыдущий экран".
95
+
Заметьте, мы передали в `useTransition` объект с конфигурацией. Это свойство `timeoutMs`, которое определяет **как долго мы готовы ждать завершения перехода**. Передавая `{timeoutMs: 3000}`, мы говорим "Если следующий профиль будет загружаться более 3 секунд, покажи большой спиннер -- но до истечения этого таймаута можно показывать предыдущий экран".
96
96
97
97
### Оборачивание setState в Переход {#wrapping-setstate-in-a-transition}
98
98
@@ -107,7 +107,7 @@ function App() {
107
107
>
108
108
```
109
109
110
-
Мы обернём обновление состояния в метод `startTransition`. Таким образом, React поймёт, что **мы не против того, чтобы React отложил это обновление состояния** если оно приведёт к нежелательному состояинию ожидания загрузки:
110
+
Мы обернём обновление состояния в метод `startTransition`. Таким образом, React поймёт, что **мы не против того, чтобы React отложил это обновление состояния** если оно приведёт к нежелательному состоянию ожидания загрузки:
111
111
112
112
```js{3,6}
113
113
<button
@@ -201,29 +201,29 @@ function App() {
201
201
* Мы обернули обновление состояния в `startTransition`, чтобы React знал, что его можно отложить.
202
202
* Мы используем `isPending`, чтобы сообщить пользователю статус перехода и отключить кнопку.
203
203
204
-
В результате, нажатие на "Next" не приводит к немедленному переходу на нежелательный экран загрузки, а оставляет нас на предыдущем экране с возможностью отоброжать прогресс по загрузке.
204
+
В результате, нажатие на "Next" не приводит к немедленному переходу на нежелательный экран загрузки, а оставляет нас на предыдущем экране с возможностью отображать прогресс загрузки.
205
205
206
206
### Где происходит обновление? {#where-does-the-update-happen}
207
207
208
-
Имплементация была не очень сложной. Однако, если начать размышлять о том, как бы это могло бы быть реализовано, всё может показаться гараздо более запутанным. Если мы обновляем состояние, почему мы не показываем результат сразу же? *Где* рендерится следующая версия `<ProfilePage>`?
208
+
Имплементация была не очень сложной. Однако, если начать размышлять о том, как бы это могло бы быть реализовано, всё может показаться гораздо более запутанным. Если мы обновляем состояние, почему мы не показываем результат сразу же? *Где* рендерится следующая версия `<ProfilePage>`?
209
209
210
-
Очевидно, обе "версии" `<ProfilePage>` существуют одновременно. Мы знаем, что старая версия существует, потому что видим её на экране и даже показывает идикатор прогресса. Также мы знаем, что и новая версия *где-то* существует, потому что как раз её мы и ожидаем!
210
+
Очевидно, обе "версии" `<ProfilePage>` существуют одновременно. Мы знаем, что старая версия существует, потому что видим её на экране и даже показывает индикатор прогресса. Также мы знаем, что и новая версия *где-то* существует, потому что как раз её мы и ожидаем!
211
211
212
212
**Но как две верси одного компонента могут существовать одновременно?**
213
213
214
-
Таким образом мы подходим к основной сути Конкурентного Режима. [Ранее мы говорили](/docs/concurrent-mode-intro.html#intentional-loading-sequences), что можно представить как будто React работает над новым состоянием в "отдельной ветке". Другой подход, представить что оборачивая обновление состояния в `startTransition` мы начинем рендерить его *"в параллельной вселенной"*, почти как в фантастическом фильме. Мы не "видим" это вселенную явно -- но мы можем получить сигнал от неё, который говорит нам о том, что какой-то процес запущен (`isPending`). Когда обновление будет готово, наши "вселенные" объединятся в одну, и мы увидим результат на экране!
214
+
Таким образом мы подходим к основной сути Конкурентного Режима. [Ранее мы говорили](/docs/concurrent-mode-intro.html#intentional-loading-sequences), что можно представить как будто React работает над новым состоянием в "отдельной ветке". Другой подход, представить что оборачивая обновление состояния в `startTransition` мы начинем рендерить его *"в параллельной вселенной"*, почти как в фантастическом фильме. Мы не "видим" это вселенную явно -- но мы можем получить сигнал от неё, который говорит нам о том, что какой-то процесс запущен (`isPending`). Когда обновление будет готово, наши "вселенные" объединятся в одну, и мы увидим результат на экране!
215
215
216
216
Поиграйте с [примером](https://codesandbox.io/s/jovial-lalande-26yep), и представьте, что так и происходит.
217
217
218
-
Конечно, рендеринг двух версий *в одно и то же время* - это илюзия, ровно как и идея о том, что все программы на вашем компьютере исполняются в один и тот же момент. Операционная система перекулючается между приложениями очень быстро. Аналогично, React может переключаться между версией, которую мы видим на экране и версией "готовящейся" к показу.
218
+
Конечно, рендеринг двух версий *в одно и то же время* - это иллюзия, ровно как и идея о том, что все программы на вашем компьютере исполняются в один и тот же момент. Операционная система переключается между приложениями очень быстро. Аналогично, React может переключаться между версией, которую мы видим на экране и версией "готовящейся" к показу.
219
219
220
220
Использование API `useTransition` позволяет сфокусироваться на желаемом результате и не думать о тонкостях имплементации. Тем не менее, полезно представлять, что обновления обёрнутые в `startTransition` происходят "в ветке" или "в другом мире".
Как мы поняли из [разобра Задержки](/docs/concurrent-mode-suspense.html), любой компонент может "задерживатсья" на любое время, если данные, которые ему необходимы ещё не готовы. Мы можем подумать над стратегий расположения границ `<Suspense>` в разных частях дерева, но не всегда этого будет достаточно.
224
+
Как мы поняли из [разбора Задержки](/docs/concurrent-mode-suspense.html), любой компонент может "задерживаться" на любое время, если данные, которые ему необходимы ещё не готовы. Мы можем подумать над стратегий расположения границ `<Suspense>` в разных частях дерева, но не всегда этого будет достаточно.
225
225
226
-
Давайте вернёмся к нашему [первому примеру Задержки](https://codesandbox.io/s/frosty-hermann-bztrp), когда у нас был только один профиль. Сейчас занные запрашиваются только однажды. Добавим кнопку "Refresh", чтобы проверять обновления с сервера.
226
+
Давайте вернёмся к нашему [первому примеру Задержки](https://codesandbox.io/s/frosty-hermann-bztrp), когда у нас был только один профиль. Сейчас данные запрашиваются только однажды. Добавим кнопку "Refresh", чтобы проверять обновления с сервера.
0 commit comments