diff --git a/src/content/reference/react/useTransition.md b/src/content/reference/react/useTransition.md index 73a754df70..3648e91aa8 100644 --- a/src/content/reference/react/useTransition.md +++ b/src/content/reference/react/useTransition.md @@ -1,10 +1,9 @@ --- title: useTransition --- - -`useTransition` is a React Hook that lets you render a part of the UI in the background. +`useTransition` — это хук React, который позволяет рендерить часть пользовательского интерфейса в фоновом режиме. ```js const [isPending, startTransition] = useTransition() @@ -16,11 +15,11 @@ const [isPending, startTransition] = useTransition() --- -## Reference {/*reference*/} +## Справочник {/*reference*/} ### `useTransition()` {/*usetransition*/} -Call `useTransition` at the top level of your component to mark some state updates as Transitions. +Вызовите `useTransition` на верхнем уровне вашего компонента, чтобы пометить некоторые обновления состояния как переходы (Transitions). ```js import { useTransition } from 'react'; @@ -31,24 +30,24 @@ function TabContainer() { } ``` -[See more examples below.](#usage) +[См. больше примеров ниже.](#usage) -#### Parameters {/*parameters*/} +#### Параметры {/*parameters*/} -`useTransition` does not take any parameters. +`useTransition` не принимает никаких параметров. -#### Returns {/*returns*/} +#### Возвращаемое значение {/*returns*/} -`useTransition` returns an array with exactly two items: +`useTransition` возвращает массив из двух элементов: -1. The `isPending` flag that tells you whether there is a pending Transition. -2. The [`startTransition` function](#starttransition) that lets you mark updates as a Transition. +1. Флаг `isPending`, который сообщает, есть ли ожидающий переход. +2. Функция [`startTransition`](#starttransition), которая позволяет пометить обновления как переход. --- ### `startTransition(action)` {/*starttransition*/} -The `startTransition` function returned by `useTransition` lets you mark an update as a Transition. +Функция `startTransition`, возвращаемая `useTransition`, позволяет пометить обновление как переход. ```js {6,8} function TabContainer() { @@ -65,9 +64,9 @@ function TabContainer() { ``` -#### Functions called in `startTransition` are called "Actions". {/*functions-called-in-starttransition-are-called-actions*/} +#### Функции, вызываемые в `startTransition`, называются «действиями» (Actions). {/*functions-called-in-starttransition-are-called-actions*/} -The function passed to `startTransition` is called an "Action". By convention, any callback called inside `startTransition` (such as a callback prop) should be named `action` or include the "Action" suffix: +Функция, передаваемая в `startTransition`, называется «действием» (Action). По соглашению, любой колбэк, вызываемый внутри `startTransition` (например, колбэк-проп), должен называться `action` или иметь суффикс "Action": ```js {1,9} function SubmitButton({ submitAction }) { @@ -93,37 +92,37 @@ function SubmitButton({ submitAction }) { -#### Parameters {/*starttransition-parameters*/} +#### Параметры {/*starttransition-parameters*/} -* `action`: A function that updates some state by calling one or more [`set` functions](/reference/react/useState#setstate). React calls `action` immediately with no parameters and marks all state updates scheduled synchronously during the `action` function call as Transitions. Any async calls that are awaited in the `action` will be included in the Transition, but currently require wrapping any `set` functions after the `await` in an additional `startTransition` (see [Troubleshooting](#react-doesnt-treat-my-state-update-after-await-as-a-transition)). State updates marked as Transitions will be [non-blocking](#marking-a-state-update-as-a-non-blocking-transition) and [will not display unwanted loading indicators](#preventing-unwanted-loading-indicators). +* `action`: Функция, которая обновляет некоторое состояние, вызывая одну или несколько [`set`-функций](/reference/react/useState#setstate). React немедленно вызывает `action` без параметров и помечает все обновления состояния, запланированные синхронно во время вызова функции `action`, как переходы. Любые асинхронные вызовы, ожидание которых происходит в `action`, будут включены в переход, но в настоящее время требуют обертывания любых `set`-функций после `await` в дополнительный `startTransition` (см. [Устранение неполадок](#react-doesnt-treat-my-state-update-after-await-as-a-transition)). Обновления состояния, помеченные как переходы, будут [неблокирующими](#marking-a-state-update-as-a-non-blocking-transition) и [не будут отображать нежелательные индикаторы загрузки](#preventing-unwanted-loading-indicators). -#### Returns {/*starttransition-returns*/} +#### Возвращаемое значение {/*starttransition-returns*/} -`startTransition` does not return anything. +`startTransition` ничего не возвращает. -#### Caveats {/*starttransition-caveats*/} +#### Ограничения {/*starttransition-caveats*/} -* `useTransition` is a Hook, so it can only be called inside components or custom Hooks. If you need to start a Transition somewhere else (for example, from a data library), call the standalone [`startTransition`](/reference/react/startTransition) instead. +* `useTransition` — это хук, поэтому его можно вызывать только внутри компонентов или пользовательских хуков. Если вам нужно начать переход где-то еще (например, из библиотеки данных), вместо этого вызовите автономный [`startTransition`](/reference/react/startTransition). -* You can wrap an update into a Transition only if you have access to the `set` function of that state. If you want to start a Transition in response to some prop or a custom Hook value, try [`useDeferredValue`](/reference/react/useDeferredValue) instead. +* Вы можете обернуть обновление в переход только в том случае, если у вас есть доступ к `set`-функции этого состояния. Если вы хотите начать переход в ответ на какой-либо проп или значение пользовательского хука, вместо этого попробуйте [`useDeferredValue`](/reference/react/useDeferredValue). -* The function you pass to `startTransition` is called immediately, marking all state updates that happen while it executes as Transitions. If you try to perform state updates in a `setTimeout`, for example, they won't be marked as Transitions. +* Функция, которую вы передаете в `startTransition`, вызывается немедленно, помечая все обновления состояния, которые происходят во время ее выполнения, как переходы. Если вы попытаетесь выполнить обновления состояния в `setTimeout`, например, они не будут помечены как переходы. -* You must wrap any state updates after any async requests in another `startTransition` to mark them as Transitions. This is a known limitation that we will fix in the future (see [Troubleshooting](#react-doesnt-treat-my-state-update-after-await-as-a-transition)). +* Любые обновления состояния после асинхронных запросов должны быть обернуты в другой `startTransition`, чтобы пометить их как переходы. Это известное ограничение, которое мы исправим в будущем (см. [Устранение неполадок](#react-doesnt-treat-my-state-update-after-await-as-a-transition)). -* The `startTransition` function has a stable identity, so you will often see it omitted from Effect dependencies, but including it will not cause the Effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) +* Функция `startTransition` имеет стабильную идентичность, поэтому вы часто увидите, что она опущена из зависимостей эффекта, но ее включение не приведет к срабатыванию эффекта. Если линтер позволяет вам опустить зависимость без ошибок, это безопасно. [Узнайте больше об удалении зависимостей эффекта.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) -* A state update marked as a Transition will be interrupted by other state updates. For example, if you update a chart component inside a Transition, but then start typing into an input while the chart is in the middle of a re-render, React will restart the rendering work on the chart component after handling the input update. +* Обновление состояния, помеченное как переход, будет прервано другими обновлениями состояния. Например, если вы обновляете компонент диаграммы внутри перехода, а затем начинаете вводить текст в поле ввода, пока диаграмма находится в середине повторного рендеринга, React перезапустит работу по рендерингу компонента диаграммы после обработки обновления ввода. -* Transition updates can't be used to control text inputs. +* Переходы нельзя использовать для управления текстовыми полями ввода. -* If there are multiple ongoing Transitions, React currently batches them together. This is a limitation that may be removed in a future release. +* Если существует несколько одновременных переходов, React в настоящее время группирует их вместе. Это ограничение может быть снято в будущих версиях. -## Usage {/*usage*/} +## Использование {/*usage*/} -### Perform non-blocking updates with Actions {/*perform-non-blocking-updates-with-actions*/} +### Выполнение неблокирующих обновлений с помощью Actions {/*perform-non-blocking-updates-with-actions*/} -Call `useTransition` at the top of your component to create Actions, and access the pending state: +Вызовите `useTransition` в верхней части вашего компонента, чтобы создать Actions и получить доступ к состоянию ожидания: ```js [[1, 4, "isPending"], [2, 4, "startTransition"]] import {useState, useTransition} from 'react'; @@ -134,12 +133,12 @@ function CheckoutForm() { } ``` -`useTransition` returns an array with exactly two items: +`useTransition` возвращает массив ровно из двух элементов: -1. The `isPending` flag that tells you whether there is a pending Transition. -2. The `startTransition` function that lets you create an Action. +1. Флаг `isPending`, который сообщает вам, есть ли ожидающий Transition. +2. Функция `startTransition`, которая позволяет вам создавать Action. -To start a Transition, pass a function to `startTransition` like this: +Чтобы запустить Transition, передайте функцию в `startTransition` следующим образом: ```js import {useState, useTransition} from 'react'; @@ -161,17 +160,17 @@ function CheckoutForm() { } ``` -The function passed to `startTransition` is called the "Action". You can update state and (optionally) perform side effects within an Action, and the work will be done in the background without blocking user interactions on the page. A Transition can include multiple Actions, and while a Transition is in progress, your UI stays responsive. For example, if the user clicks a tab but then changes their mind and clicks another tab, the second click will be immediately handled without waiting for the first update to finish. +Функция, переданная в `startTransition`, называется "Action". Вы можете обновлять состояние и (опционально) выполнять побочные эффекты внутри Action, и работа будет выполнена в фоновом режиме, не блокируя взаимодействие пользователя на странице. Transition может включать несколько Actions, и пока Transition выполняется, ваш UI остается отзывчивым. Например, если пользователь нажимает на вкладку, но затем передумывает и нажимает на другую вкладку, второе нажатие будет немедленно обработано без ожидания завершения первого обновления. -To give the user feedback about in-progress Transitions, the `isPending` state switches to `true` at the first call to `startTransition`, and stays `true` until all Actions complete and the final state is shown to the user. Transitions ensure side effects in Actions to complete in order to [prevent unwanted loading indicators](#preventing-unwanted-loading-indicators), and you can provide immediate feedback while the Transition is in progress with `useOptimistic`. +Чтобы предоставить пользователю обратную связь о выполняющихся Transitions, состояние `isPending` переключается на `true` при первом вызове `startTransition` и остается `true` до тех пор, пока все Actions не завершатся и конечное состояние не будет показано пользователю. Transitions гарантируют, что побочные эффекты в Actions завершатся, чтобы [предотвратить нежелательные индикаторы загрузки](#preventing-unwanted-loading-indicators), и вы можете предоставить немедленную обратную связь во время выполнения Transition с помощью `useOptimistic`. - + -#### Updating the quantity in an Action {/*updating-the-quantity-in-an-action*/} +#### Обновление количества в Action {/*updating-the-quantity-in-an-action*/} -In this example, the `updateQuantity` function simulates a request to the server to update the item's quantity in the cart. This function is *artificially slowed down* so that it takes at least a second to complete the request. +В этом примере функция `updateQuantity` имитирует запрос к серверу для обновления количества товара в корзине. Эта функция *искусственно замедлена*, так что для завершения запроса требуется не менее одной секунды. -Update the quantity multiple times quickly. Notice that the pending "Total" state is shown while any requests are in progress, and the "Total" updates only after the final request is complete. Because the update is in an Action, the "quantity" can continue to be updated while the request is in progress. +Быстро обновите количество несколько раз. Обратите внимание, что ожидающее состояние "Total" отображается во время выполнения любых запросов, а "Total" обновляется только после завершения последнего запроса. Поскольку обновление находится в Action, "quantity" может продолжать обновляться во время выполнения запроса. @@ -201,8 +200,8 @@ export default function App({}) { const [isPending, startTransition] = useTransition(); const updateQuantityAction = async newQuantity => { - // To access the pending state of a transition, - // call startTransition again. + // Чтобы получить доступ к состоянию ожидания transition, + // вызовите startTransition снова. startTransition(async () => { const savedQuantity = await updateQuantity(newQuantity); startTransition(() => { @@ -227,7 +226,7 @@ import { startTransition } from "react"; export default function Item({action}) { function handleChange(event) { - // To expose an action prop, await the callback in startTransition. + // Чтобы предоставить action как prop, ожидайте callback в startTransition. startTransition(async () => { await action(event.target.value); }) @@ -268,7 +267,7 @@ export default function Total({quantity, isPending}) { ```js src/api.js export async function updateQuantity(newQuantity) { return new Promise((resolve, reject) => { - // Simulate a slow network request. + // Имитация медленного сетевого запроса. setTimeout(() => { resolve(newQuantity); }, 2000); @@ -305,22 +304,22 @@ export async function updateQuantity(newQuantity) { -This is a basic example to demonstrate how Actions work, but this example does not handle requests completing out of order. When updating the quantity multiple times, it's possible for the previous requests to finish after later requests causing the quantity to update out of order. This is a known limitation that we will fix in the future (see [Troubleshooting](#my-state-updates-in-transitions-are-out-of-order) below). +Это базовый пример, демонстрирующий работу Actions, но он не обрабатывает запросы, завершающиеся не по порядку. При многократном обновлении количества возможно, что предыдущие запросы завершатся после более поздних, что приведет к обновлению количества не по порядку. Это известное ограничение, которое мы исправим в будущем (см. [Устранение неполадок](#my-state-updates-in-transitions-are-out-of-order) ниже). -For common use cases, React provides built-in abstractions such as: +Для распространенных сценариев использования React предоставляет встроенные абстракции, такие как: - [`useActionState`](/reference/react/useActionState) -- [`
` actions](/reference/react-dom/components/form) +- [Actions ``](/reference/react-dom/components/form) - [Server Functions](/reference/rsc/server-functions) -These solutions handle request ordering for you. When using Transitions to build your own custom hooks or libraries that manage async state transitions, you have greater control over the request ordering, but you must handle it yourself. +Эти решения обрабатывают порядок запросов за вас. При использовании Transitions для создания собственных пользовательских хуков или библиотек, управляющих асинхронными переходами состояния, вы имеете больший контроль над порядком запросов, но должны обрабатывать его самостоятельно. -#### Updating the quantity without an Action {/*updating-the-users-name-without-an-action*/} +#### Обновление количества без Action {/*updating-the-users-name-without-an-action*/} -In this example, the `updateQuantity` function also simulates a request to the server to update the item's quantity in the cart. This function is *artificially slowed down* so that it takes at least a second to complete the request. +В этом примере функция `updateQuantity` также имитирует запрос к серверу для обновления количества товара в корзине. Эта функция *искусственно замедлена*, так что для завершения запроса требуется не менее одной секунды. -Update the quantity multiple times quickly. Notice that the pending "Total" state is shown while any requests is in progress, but the "Total" updates multiple times for each time the "quantity" was clicked: +Быстро обновите количество несколько раз. Обратите внимание, что ожидающее состояние "Total" отображается во время выполнения любого запроса, но "Total" обновляется несколько раз при каждом нажатии на "quantity": @@ -350,7 +349,7 @@ export default function App({}) { const [isPending, setIsPending] = useState(false); const onUpdateQuantity = async newQuantity => { - // Manually set the isPending State. + // Вручную установите состояние isPending. setIsPending(true); const savedQuantity = await updateQuantity(newQuantity); setIsPending(false); @@ -410,7 +409,7 @@ export default function Total({quantity, isPending}) { ```js src/api.js export async function updateQuantity(newQuantity) { return new Promise((resolve, reject) => { - // Simulate a slow network request. + // Имитация медленного сетевого запроса. setTimeout(() => { resolve(newQuantity); }, 2000); @@ -447,7 +446,7 @@ export async function updateQuantity(newQuantity) { -A common solution to this problem is to prevent the user from making changes while the quantity is updating: +Распространенным решением этой проблемы является запрет пользователю вносить изменения во время обновления количества: @@ -467,7 +466,7 @@ A common solution to this problem is to prevent the user from making changes whi ``` ```js src/App.js -import { useState, useTransition } from "react"; +import { useState } from "react"; import { updateQuantity } from "./api"; import Item from "./Item"; import Total from "./Total"; @@ -478,7 +477,7 @@ export default function App({}) { const onUpdateQuantity = async event => { const newQuantity = event.target.value; - // Manually set the isPending state. + // Вручную установите состояние isPending. setIsPending(true); const savedQuantity = await updateQuantity(newQuantity); setIsPending(false); @@ -536,7 +535,7 @@ export default function Total({quantity, isPending}) { ```js src/api.js export async function updateQuantity(newQuantity) { return new Promise((resolve, reject) => { - // Simulate a slow network request. + // Имитация медленного сетевого запроса. setTimeout(() => { resolve(newQuantity); }, 2000); @@ -573,7 +572,7 @@ export async function updateQuantity(newQuantity) { -This solution makes the app feel slow, because the user must wait each time they update the quantity. It's possible to add more complex handling manually to allow the user to interact with the UI while the quantity is updating, but Actions handle this case with a straight-forward built-in API. +Это решение делает приложение медленным, потому что пользователю приходится ждать каждый раз при обновлении количества. Можно добавить более сложную обработку вручную, чтобы позволить пользователю взаимодействовать с UI во время обновления количества, но Actions обрабатывают этот случай с помощью простого встроенного API. @@ -581,11 +580,11 @@ This solution makes the app feel slow, because the user must wait each time they --- -### Exposing `action` prop from components {/*exposing-action-props-from-components*/} +### Предоставление пропса `action` из компонентов {/*exposing-action-props-from-components*/} -You can expose an `action` prop from a component to allow a parent to call an Action. +Вы можете предоставить пропс `action` из компонента, чтобы родительский компонент мог вызывать Action. -For example, this `TabButton` component wraps its `onClick` logic in an `action` prop: +Например, этот компонент `TabButton` оборачивает свою логику `onClick` в пропс `action`: ```js {8-12} export default function TabButton({ action, children, isActive }) { @@ -596,8 +595,8 @@ export default function TabButton({ action, children, isActive }) { return (