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
Copy file name to clipboardexpand all lines: src/content/reference/react/useEffect.md
+36-36
Original file line number
Diff line number
Diff line change
@@ -1757,31 +1757,31 @@ function MyComponent() {
1757
1757
1758
1758
---
1759
1759
1760
-
## Troubleshooting {/*troubleshooting*/}
1760
+
## Устранение неполадок {/*troubleshooting*/}
1761
1761
1762
-
### My Effect runs twice when the component mounts {/*my-effect-runs-twice-when-the-component-mounts*/}
1762
+
### Мой эффект запускается дважды, когда компонент монтируется {/*my-effect-runs-twice-when-the-component-mounts*/}
1763
1763
1764
-
When Strict Mode is on, in development, React runs setup and cleanup one extra time before the actual setup.
1764
+
В строгом режиме во время разработки React запускает один предварительный цикл установки и сброса перед тем, как запустить установку как обычно.
1765
1765
1766
-
This is a stress-test that verifies your Effect’s logic is implemented correctly. Ifthis causes visible issues, your cleanup function is missing some logic. The cleanup function should stop or undo whatever the setup function was doing. The rule of thumb is that the user shouldn’t be able to distinguish between the setup being called once (asinproduction) and a setup → cleanup → setup sequence (as in development).
1766
+
Это такой стресс-тест, проверяющий, что логика вашего эффекта реализована правильно. Если вы видите, что тест создаёт проблемы -- значит у вас в логике сброса чего-то не хватает. Код сброса должен отменять и откатывать всю ту работу, которую проделал код установки. Эмпирическое правило такое: пользователь не должен замечать разницы, вызвалась установка один раз (как в продакшене) или последовательностью *установка* → *сброс* → *установка* (как во время разработки).
1767
1767
1768
-
Read more about [how this helps find bugs](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed) and [how to fix your logic.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development)
1768
+
Изучите подробнее, [как этот тест помогает выявлять дефекты,](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed) и [как исправить логику эффекта.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development)
1769
1769
1770
1770
---
1771
1771
1772
-
### My Effect runs after every re-render {/*my-effect-runs-after-every-re-render*/}
1772
+
### Мой эффект запускается при каждом рендеринге {/*my-effect-runs-after-every-re-render*/}
1773
1773
1774
-
First, check that you haven't forgotten to specify the dependency array:
1774
+
Для начала убедитесь, что не забыли указать массив зависимостей:
1775
1775
1776
1776
```js {3}
1777
1777
useEffect(() => {
1778
1778
// ...
1779
-
}); // 🚩 No dependency array: re-runs after every render!
1779
+
}); // 🚩 Нет массива зависимостей: эффект срабатывает при каждом рендеринге!
1780
1780
```
1781
1781
1782
-
If you've specified the dependency array but your Effect still re-runs in a loop, it's because one of your dependencies is different on every re-render.
1782
+
Если вы указали массив зависимостей, но эффект всё равно постоянно перезапускается -- значит при каждом рендеринге изменяется какая-то из зависимостей.
1783
1783
1784
-
You can debug this problem by manually logging your dependencies to the console:
1784
+
Чтобы отладить проблему, выведите массив зависимостей в консоль:
1785
1785
1786
1786
```js {5}
1787
1787
useEffect(() => {
@@ -1791,58 +1791,58 @@ You can debug this problem by manually logging your dependencies to the console:
1791
1791
console.log([serverUrl, roomId]);
1792
1792
```
1793
1793
1794
-
You can then right-click on the arrays from different re-renders in the console and select "Store as a global variable" for both of them. Assuming the first one got saved as `temp1` and the second one got saved as `temp2`, you can then use the browser console to check whether each dependency in both arrays is the same:
1794
+
Затем выберите в консоли два массива из двух разных проходов рендеринга, по каждому кликните правой кнопкой мыши и выберите в меню "Сохранить как глобальную переменную" ("Store as a global variable"). Если, допустим, первый массив сохранился в переменную`temp1`, а второй -- в `temp2`, то теперь можно в консоли браузера вот так проверить на равенство каждую отдельную зависимость:
1795
1795
1796
1796
```js
1797
-
Object.is(temp1[0], temp2[0]); // Is the first dependency the same between the arrays?
1798
-
Object.is(temp1[1], temp2[1]); // Is the second dependency the same between the arrays?
1799
-
Object.is(temp1[2], temp2[2]); // ... and so on for every dependency ...
1797
+
Object.is(temp1[0], temp2[0]); // Совпадает ли в массивах первая зависимость?
1798
+
Object.is(temp1[1], temp2[1]); // Совпадает ли в массивах вторая зависимость?
1799
+
Object.is(temp1[2], temp2[2]); // ... и так для каждой зависимости ...
1800
1800
```
1801
1801
1802
-
When you find the dependency that is different on every re-render, you can usually fix it in one of these ways:
1802
+
Так вы найдёте, какая зависимость изменяется при каждом рендеринге. Поправить её обычно можно одним из следующих способов:
1803
1803
1804
-
- [Updating state based on previous state from an Effect](#updating-state-based-on-previous-state-from-an-effect)
- [Removing unnecessary function dependencies](#removing-unnecessary-function-dependencies)
1807
-
- [Reading the latest props and state from an Effect](#reading-the-latest-props-and-state-from-an-effect)
1804
+
- [Обновлять в эффекте состояние на основе предыдущего состояния.](#updating-state-based-on-previous-state-from-an-effect)
1805
+
- [Устранить лишнюю зависимость от объекта.](#removing-unnecessary-object-dependencies)
1806
+
- [Устранить лишнюю зависимость от функции.](#removing-unnecessary-function-dependencies)
1807
+
- [Читать в эффекте актуальные пропсы или состояние.](#reading-the-latest-props-and-state-from-an-effect)
1808
1808
1809
-
As a last resort (if these methods didn't help), wrap its creation with[`useMemo`](/reference/react/useMemo#memoizing-a-dependency-of-another-hook) or [`useCallback`](/reference/react/useCallback#preventing-an-effect-from-firing-too-often) (for functions).
1809
+
В крайнем случае (если ни один из способов выше не подошёл) можно обернуть вычисление зависимости в [`useMemo`](/reference/react/useMemo#memoizing-a-dependency-of-another-hook), либо в [`useCallback`](/reference/react/useCallback#preventing-an-effect-from-firing-too-often), если это функция.
1810
1810
1811
1811
---
1812
1812
1813
-
### My Effect keeps re-running in an infinite cycle {/*my-effect-keeps-re-running-in-an-infinite-cycle*/}
1813
+
### Мой эффект без конца перезапускается {/*my-effect-keeps-re-running-in-an-infinite-cycle*/}
1814
1814
1815
-
If your Effect runs in an infinite cycle, these two things must be true:
1815
+
Если ваш эффект перезапускается в бесконечном цикле, то скорее всего имеют место быть оба следующих факта:
1816
1816
1817
-
-Your Effect is updating some state.
1818
-
-That state leads to a re-render, which causes the Effect's dependencies to change.
1817
+
-Ваш эффект изменяет состояние.
1818
+
-Изменение состояния перезапускает рендеринг, и в процессе изменяются зависимости эффекта.
1819
1819
1820
-
Before you start fixing the problem, ask yourself whether your Effect is connecting to some external system (like DOM, network, a third-party widget, and so on). Why does your Effect need to set state? Does it synchronize with that external system? Or are you trying to manage your application's data flow with it?
1820
+
Перед тем, как приступить к исправлению, задайтесь вопросом: подключается ли к внешней системе ваш эффект (кDOM, к сети, к стороннему виджету, и т.п.)? Зачем этому эффекту изменять состояние? Он так синхронизируется с внешней системой? Или вы так просто пытаетесь управлять потоком данных в приложении?
1821
1821
1822
-
If there is no external system, consider whether [removing the Effect altogether](/learn/you-might-not-need-an-effect) would simplify your logic.
1822
+
Если подключения к внешней системе нет, то возможно вашу логику можно упростить, если [избавиться от эффекта как такового.](/learn/you-might-not-need-an-effect)
1823
1823
1824
-
If you're genuinely synchronizing with some external system, think about why and under what conditions your Effect should update the state. Has something changed that affects your component's visual output? If you need to keep track of some data that isn't used by rendering, a [ref](/reference/react/useRef#referencing-a-value-with-a-ref) (which doesn't trigger re-renders) might be more appropriate. Verify your Effect doesn't update the state (and trigger re-renders) more than needed.
1824
+
Если вы действительно пытаетесь синхронизироваться с внешней системой, то подумайте, зачем и при каких именно условиях эффект должен изменять состояние. Влияют ли изменения на визуальное отображение компонента? Если нужно отслеживать какие-то данные, не участвующие в рендеринге, то возможно вам больше подойдёт [реф](/reference/react/useRef#referencing-a-value-with-a-ref) (без перезапуска рендеринга). Если нужно обновлять состояние (с перезапуском рендеринга), убедитесь, что обновление не происходит чаще, чем нужно.
1825
1825
1826
-
Finally, if your Effect is updating the state at the right time, but there is still a loop, it's because that state update leads to one of the Effect's dependencies changing. [Read how to debug dependency changes.](/reference/react/useEffect#my-effect-runs-after-every-re-render)
1826
+
Наконец, если эффект обновляет состояние ровно тогда, когда это нужно, но всё равно без конца перезапускается -- значит обновление состояния приводит к изменению какой-то зависимости эффекта. [Почитайте, как можно отладить изменения в зависимостях.](/reference/react/useEffect#my-effect-runs-after-every-re-render)
1827
1827
1828
1828
---
1829
1829
1830
-
### My cleanup logic runs even though my component didn't unmount {/*my-cleanup-logic-runs-even-though-my-component-didnt-unmount*/}
1830
+
### Моя логика сброса запустилась, хотя компонент не размонтируется {/*my-cleanup-logic-runs-even-though-my-component-didnt-unmount*/}
1831
1831
1832
-
The cleanup function runs not only during unmount, but before every re-render with changed dependencies. Additionally, in development, React [runs setup+cleanup one extra time immediately after component mounts.](#my-effect-runs-twice-when-the-component-mounts)
1832
+
Сброс эффекта происходит не только при размонтировании, но и после каждого рендеринга, в котором изменились зависимости. Кроме того, в режиме разработки React [делает при монтировании один дополнительный запуск установки и сброса.](#my-effect-runs-twice-when-the-component-mounts)
1833
1833
1834
-
If you have cleanup code without corresponding setup code, it's usually a code smell:
1834
+
Если для вашего кода сброса нет соответствующего кода установки -- обычно это признак проблем в коде:
1835
1835
1836
1836
```js {2-5}
1837
1837
useEffect(() => {
1838
-
// 🔴 Avoid: Cleanup logic without corresponding setup logic
1838
+
// 🔴 Не делайте так: логика сброса не соответствует логике установки.
1839
1839
return () => {
1840
1840
doSomething();
1841
1841
};
1842
1842
}, []);
1843
1843
```
1844
1844
1845
-
Your cleanup logic should be "symmetrical" to the setup logic, and should stop or undo whatever setup did:
1845
+
Ваша логика сброса должна быть "симметрична" логике установки, отменяя и откатывая всю ту работу, которую проделала установка:
1846
1846
1847
1847
```js {2-3,5}
1848
1848
useEffect(() => {
@@ -1854,10 +1854,10 @@ Your cleanup logic should be "symmetrical" to the setup logic, and should stop o
1854
1854
}, [serverUrl, roomId]);
1855
1855
```
1856
1856
1857
-
[Learn how the Effect lifecycle is different from the component's lifecycle.](/learn/lifecycle-of-reactive-effects#the-lifecycle-of-an-effect)
1857
+
[Изучите, в чём отличие жизненного цикла эффекта по сравнению с жизненным циклом компонента.](/learn/lifecycle-of-reactive-effects#the-lifecycle-of-an-effect)
1858
1858
1859
1859
---
1860
1860
1861
-
### My Effect does something visual, and I see a flicker before it runs {/*my-effect-does-something-visual-and-i-see-a-flicker-before-it-runs*/}
1861
+
### Мой эффект делает визуальные изменения, но я вижу мерцание перед его срабатыванием {/*my-effect-does-something-visual-and-i-see-a-flicker-before-it-runs*/}
1862
1862
1863
-
If your Effect must block the browser from [painting the screen,](/learn/render-and-commit#epilogue-browser-paint) replace `useEffect`with [`useLayoutEffect`](/reference/react/useLayoutEffect). Note that **this shouldn't be needed for the vast majority of Effects.** You'll only need this if it's crucial to run your Effect before the browser paint: for example, to measure and position a tooltip before the user sees it.
1863
+
Если вам нужно, чтобы браузер не [отрисовывал экран,](/learn/render-and-commit#epilogue-browser-paint) пока не сработает эффект, то замените `useEffect`на [`useLayoutEffect`](/reference/react/useLayoutEffect). Однако помните, что **для подавляющего большинства эффектов такое не должно быть нужно.**Замена будет нужна только там, где критически важно, чтобы эффект сработал до отрисовки браузером: например, чтобы эффект вычислил размеры и расположение для всплывающей подсказки до того, как её увидит пользователь.
0 commit comments