From 025503315fced31714595fa71229afc010d4c812 Mon Sep 17 00:00:00 2001 From: SmolinPavel Date: Tue, 25 Feb 2020 10:01:00 +0300 Subject: [PATCH 1/2] Start translating Concurent mode patterns article --- content/docs/concurrent-mode-patterns.md | 109 ++++++++++++----------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/content/docs/concurrent-mode-patterns.md b/content/docs/concurrent-mode-patterns.md index 137d6f182..c61170809 100644 --- a/content/docs/concurrent-mode-patterns.md +++ b/content/docs/concurrent-mode-patterns.md @@ -23,11 +23,12 @@ next: concurrent-mode-adoption.html -Usually, when we update the state, we expect to see changes on the screen immediately. This makes sense because we want to keep our app responsive to user input. However, there are cases where we might prefer to **defer an update from appearing on the screen**. +Обновляя состояние, мы обычно ожидаем сразу же увидеть изменения на экране. В этом есть смысл, ведь мы хотим, чтобы наше приложение было отзывчивым к действиям пользователя. Тем не менее, существуют сценарии, при которых предпочтительно **отложить появление обновления на экране**. -For example, if we switch from one page to another, and none of the code or data for the next screen has loaded yet, it might be frustrating to immediately see a blank page with a loading indicator. We might prefer to stay longer on the previous screen. Implementing this pattern has historically been difficult in React. Concurrent Mode offers a new set of tools to do that. +Например, если мы переходим с одной страницы на другую, и часть кода или данных для следующего экрана ещё не загружена, может быть странным сразу увидеть пустую страницу с индикатором загрузки. +Скорее всего мы захотим задержаться на предыдущем экране. Реализация такого паттерна всегда была достаточно сложной в React. Конкурентный режим предоставляет новый набор интсрументов для решения таких задач. -- [Transitions](#transitions) +- [Переходы](#transitions) - [Wrapping setState in a Transition](#wrapping-setstate-in-a-transition) - [Adding a Pending Indicator](#adding-a-pending-indicator) - [Reviewing the Changes](#reviewing-the-changes) @@ -47,31 +48,31 @@ For example, if we switch from one page to another, and none of the code or data - [SuspenseList](#suspenselist) - [Next Steps](#next-steps) -## Transitions {#transitions} +## Переходы {#transitions} -Let's revisit [this demo](https://codesandbox.io/s/infallible-feather-xjtbu) from the previous page about [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html). +Давайте вернёмся к [примеру](https://codesandbox.io/s/infallible-feather-xjtbu) с предыдущей страницы про [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html). -When we click the "Next" button to switch the active profile, the existing page data immediately disappears, and we see the loading indicator for the whole page again. We can call this an "undesirable" loading state. **It would be nice if we could "skip" it and wait for some content to load before transitioning to the new screen.** +Когда мы нажимаем на кнопку "Next", чтобы переключить активный профиль, данные текущей страницы моментально пропадают и мы видим индикатор загрузки для всей страницы снова. Мы можем сказать, что это "нежелательное" состояние загрузки. **Было бы хорошо, если бы мы могли "пропустить" его и подождать пока загрузится конент перед переходом на новый экран** -React offers a new built-in `useTransition()` Hook to help with this. +React предлагает новый встроенный хук `useTransition()`, чтобы решить эту задачу. -We can use it in three steps. +Чтобы его использовать, нам нужно выполнить три шага. -First, we'll make sure that we're actually using Concurrent Mode. We'll talk more about [adopting Concurrent Mode](/docs/concurrent-mode-adoption.html) later, but for now it's sufficient to know that we need to use `ReactDOM.createRoot()` rather than `ReactDOM.render()` for this feature to work: +Во-первых, мы убедимся, что мы включили конкурентный режим. Мы поговорим подбробнее о [внедрении конекурентного режима](/docs/concurrent-mode-adoption.html) позже, но пока отметим, что необходимо использовать `ReactDOM.createRoot()` вместо `ReactDOM.render()` для того, чтобы воспользоваться этим решением: ```js const rootElement = document.getElementById("root"); -// Opt into Concurrent Mode +// Включаем конкурентный режим ReactDOM.createRoot(rootElement).render(); ``` -Next, we'll add an import for the `useTransition` Hook from React: +Далее, добавим импорт хука `useTransition` из React: ```js import React, { useState, useTransition, Suspense } from "react"; ``` -Finally, we'll use it inside the `App` component: +Наконец, используем этот хук в компоненте `App`: ```js{3-5} function App() { @@ -82,18 +83,20 @@ function App() { // ... ``` -**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`: +**Сам по себе, этот код пока ничего не делает.** Для того чтобы настроить переходы состояния, нам нужно использовать возращаемое значение данного хука. Результатом вызова `useTransition` будут два значения: + +* `startTransition` является функцией. Мы будем использовать её для того чтобы сказать React *какое* обновление состояения мы хотим отложить. +* `isPending` представляет собой булево значение. Через него React сообщает нам происходит переход в данный момент или нет. -* `startTransition` is a function. We'll use it to tell React *which* state update we want to defer. -* `isPending` is a boolean. It's React telling us whether that transition is ongoing at the moment. +**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`: -We will use them right below. +Мы будем использовать их в примере ниже. -Note we passed a configuration object to `useTransition`. Its `timeoutMs` property specifies **how long we're willing to wait for the transition to finish**. By passing `{timeoutMs: 3000}`, we say "If the next profile takes more than 3 seconds to load, show the big spinner -- but before that timeout it's okay to keep showing the previous screen". +Заметьте, мы передали в `useTransition` объект с конфигурацией. Это свойство `timeoutMs`, которое определяет **как долго мы готовы подождить пока переход закончится**. Передавая `{timeoutMs: 3000}`, мы говорим "Если следующий профиль будет загружаться более 3 секунд, покажи большой спиннер -- но до истечения этого таймаута можно показывать предыдущий экран". -### Wrapping setState in a Transition {#wrapping-setstate-in-a-transition} +### Оборачивание setState в Переход {#wrapping-setstate-in-a-transition} -Our "Next" button click handler sets the state that switches the current profile in the state: +Обработчик кнопки "Next" обновляет состояние, что ведёт к переключению текущего профиля в состоянии: ```js{4} - Loading posts...}> + Загружаем посты...}> @@ -248,7 +251,7 @@ function ProfilePage() { } ``` -**[Try it on CodeSandbox](https://codesandbox.io/s/boring-shadow-100tf)** +**[Пример на CodeSandbox](https://codesandbox.io/s/boring-shadow-100tf)** In this example, we start data fetching at the load *and* every time you press "Refresh". We put the result of calling `fetchUserAndPosts()` into state so that components below can start reading the new data from the request we just kicked off. From befca156c92ebda89b1f3fdab115ea7c94af3af4 Mon Sep 17 00:00:00 2001 From: Anton Ahatov Date: Sat, 25 Apr 2020 11:29:15 +0300 Subject: [PATCH 2/2] Apply suggestions from code review Co-Authored-By: Oleg Shilov --- content/docs/concurrent-mode-patterns.md | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/content/docs/concurrent-mode-patterns.md b/content/docs/concurrent-mode-patterns.md index c61170809..8cc7e7773 100644 --- a/content/docs/concurrent-mode-patterns.md +++ b/content/docs/concurrent-mode-patterns.md @@ -26,7 +26,7 @@ next: concurrent-mode-adoption.html Обновляя состояние, мы обычно ожидаем сразу же увидеть изменения на экране. В этом есть смысл, ведь мы хотим, чтобы наше приложение было отзывчивым к действиям пользователя. Тем не менее, существуют сценарии, при которых предпочтительно **отложить появление обновления на экране**. Например, если мы переходим с одной страницы на другую, и часть кода или данных для следующего экрана ещё не загружена, может быть странным сразу увидеть пустую страницу с индикатором загрузки. -Скорее всего мы захотим задержаться на предыдущем экране. Реализация такого паттерна всегда была достаточно сложной в React. Конкурентный режим предоставляет новый набор интсрументов для решения таких задач. +Скорее всего мы захотим задержаться на предыдущем экране. Реализация такого паттерна всегда была достаточно сложной в React. Конкурентный режим предоставляет новый набор инструментов для решения таких задач. - [Переходы](#transitions) - [Wrapping setState in a Transition](#wrapping-setstate-in-a-transition) @@ -52,13 +52,13 @@ next: concurrent-mode-adoption.html Давайте вернёмся к [примеру](https://codesandbox.io/s/infallible-feather-xjtbu) с предыдущей страницы про [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html). -Когда мы нажимаем на кнопку "Next", чтобы переключить активный профиль, данные текущей страницы моментально пропадают и мы видим индикатор загрузки для всей страницы снова. Мы можем сказать, что это "нежелательное" состояние загрузки. **Было бы хорошо, если бы мы могли "пропустить" его и подождать пока загрузится конент перед переходом на новый экран** +Когда мы нажимаем на кнопку "Next", чтобы переключить активный профиль, данные текущей страницы моментально пропадают и мы видим индикатор загрузки для всей страницы снова. Мы можем сказать, что это "нежелательное" состояние загрузки. **Было бы хорошо, если бы мы могли "пропустить" его и подождать пока загрузится контент перед переходом на новый экран** React предлагает новый встроенный хук `useTransition()`, чтобы решить эту задачу. Чтобы его использовать, нам нужно выполнить три шага. -Во-первых, мы убедимся, что мы включили конкурентный режим. Мы поговорим подбробнее о [внедрении конекурентного режима](/docs/concurrent-mode-adoption.html) позже, но пока отметим, что необходимо использовать `ReactDOM.createRoot()` вместо `ReactDOM.render()` для того, чтобы воспользоваться этим решением: +Во-первых, мы убедимся, что мы включили конкурентный режим. Мы поговорим подробнее о [внедрении конкурентного режима](/docs/concurrent-mode-adoption.html) позже, но пока отметим, что необходимо использовать `ReactDOM.createRoot()` вместо `ReactDOM.render()` для того, чтобы воспользоваться этим решением: ```js const rootElement = document.getElementById("root"); @@ -83,16 +83,16 @@ function App() { // ... ``` -**Сам по себе, этот код пока ничего не делает.** Для того чтобы настроить переходы состояния, нам нужно использовать возращаемое значение данного хука. Результатом вызова `useTransition` будут два значения: +**Сам по себе, этот код пока ничего не делает.** Для того чтобы настроить переходы состояния, нам нужно использовать возвращаемое значение данного хука. Результатом вызова `useTransition` будут два значения: -* `startTransition` является функцией. Мы будем использовать её для того чтобы сказать React *какое* обновление состояения мы хотим отложить. +* `startTransition` является функцией. Мы будем использовать её для того чтобы сказать React *какое* обновление состояния мы хотим отложить. * `isPending` представляет собой булево значение. Через него React сообщает нам происходит переход в данный момент или нет. **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`: Мы будем использовать их в примере ниже. -Заметьте, мы передали в `useTransition` объект с конфигурацией. Это свойство `timeoutMs`, которое определяет **как долго мы готовы подождить пока переход закончится**. Передавая `{timeoutMs: 3000}`, мы говорим "Если следующий профиль будет загружаться более 3 секунд, покажи большой спиннер -- но до истечения этого таймаута можно показывать предыдущий экран". +Заметьте, мы передали в `useTransition` объект с конфигурацией. Это свойство `timeoutMs`, которое определяет **как долго мы готовы ждать завершения перехода**. Передавая `{timeoutMs: 3000}`, мы говорим "Если следующий профиль будет загружаться более 3 секунд, покажи большой спиннер -- но до истечения этого таймаута можно показывать предыдущий экран". ### Оборачивание setState в Переход {#wrapping-setstate-in-a-transition} @@ -107,7 +107,7 @@ function App() { > ``` - Мы обернём обновление состояния в метод `startTransition`. Таким образом, React поймёт, что **мы не против того, чтобы React отложил это обновление состояния** если оно приведёт к нежелательному состояинию ожидания загрузки: + Мы обернём обновление состояния в метод `startTransition`. Таким образом, React поймёт, что **мы не против того, чтобы React отложил это обновление состояния** если оно приведёт к нежелательному состоянию ожидания загрузки: ```js{3,6}