Skip to content

Sync with reactjs.org @ 1f2dbb7a #285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Apr 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
905a113
Add React Rally 2019 (#1840)
BrianMitchL Mar 18, 2019
806da34
Add a DOM measurement recipe to Hooks FAQ (#1843)
gaearon Mar 19, 2019
ac4aa65
Add more explanations to Hooks API page (#1845)
gaearon Mar 19, 2019
b1bc193
Document useContext bailout strategy (#1848)
gaearon Mar 19, 2019
1f2dbb7
Update languages for Simplified Chinese completion (#1854)
tesseralis Mar 20, 2019
aad51f2
merging all conflicts
reactjs-translation-bot Mar 22, 2019
9bfaa3d
[ru.reactjs.org] fix sync conflicts
gcor Mar 23, 2019
11001c0
fix after review
gcor Mar 30, 2019
b5fd7b9
fix after review
gcor Mar 30, 2019
7e502fb
fix after review
gcor Mar 30, 2019
a22c4b5
Merge pull request #286 from gcor/sync-1f2dbb7a
gcor Apr 1, 2019
0f15d66
Update content/docs/hooks-reference.md
gcor Apr 1, 2019
bc33957
Update content/docs/hooks-reference.md
gcor Apr 1, 2019
4ae90f6
Update content/docs/hooks-faq.md
lex111 Apr 2, 2019
c50331e
Update content/docs/hooks-faq.md
lex111 Apr 2, 2019
2d37a5e
Update content/docs/hooks-faq.md
lex111 Apr 2, 2019
ba24f1d
Update content/docs/hooks-reference.md
lex111 Apr 2, 2019
42d54fd
Update content/docs/hooks-reference.md
lex111 Apr 2, 2019
402c0a9
Update content/docs/hooks-reference.md
lex111 Apr 2, 2019
3cf2d73
Update content/docs/hooks-faq.md
lex111 Apr 2, 2019
cfb5e29
Update content/docs/hooks-faq.md
lex111 Apr 2, 2019
6a4edbb
Update content/docs/hooks-reference.md
lex111 Apr 2, 2019
b6c974c
Update content/docs/hooks-reference.md
gcor Apr 2, 2019
3b7df89
Apply suggestions from code review
lex111 Apr 2, 2019
ce39f1d
Update content/docs/hooks-reference.md
gcor Apr 2, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions content/community/conferences.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ July 15-21, 2019. New York City, USA

[Website](https://reactweek.nyc) - [Twitter](https://twitter.com/ReactWeek)

### React Rally 2019
August 22-23, 2019. Salt Lake City, USA.

[Website](https://www.reactrally.com/) - [Twitter](https://twitter.com/ReactRally) - [Instagram](https://www.instagram.com/reactrally/)

### ComponentsConf 2019 {#componentsconf-2019}
September 6, 2019 in Melbourne, Australia
[Website](https://www.componentsconf.com.au/) - [Twitter](https://twitter.com/componentsconf)
Expand Down
64 changes: 59 additions & 5 deletions content/docs/hooks-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ prev: hooks-reference.html
* [Как я могу реализовать `getDerivedStateFromProps`?](#how-do-i-implement-getderivedstatefromprops)
* [Существует что-нибудь наподобие forceUpdate?](#is-there-something-like-forceupdate)
* [Могу ли я изменить реф, переданный в функциональный компонент?](#can-i-make-a-ref-to-a-function-component)
* [Как я могу измерить узел DOM?](#how-can-i-measure-a-dom-node)
* [Что значит `const [thing, setThing] = useState()`?](#what-does-const-thing-setthing--usestate-mean)
* [Оптимизации производительности](#performance-optimizations)
* [Могу ли я пропустить эффект при обновлениях?](#can-i-skip-an-effect-on-updates)
Expand Down Expand Up @@ -403,7 +404,7 @@ function Example() {

Если вы намеренно хотите считать из асинхронного колбэка *свежайшее* состояние, вы можете сперва сохранить его [в реф](/docs/hooks-faq.html#is-there-something-like-instance-variables), потом изменить его и затем считать его из рефа.

Наконец, возможна другая ситуация, почему вы видите устаревшие пропсы или состояние: когда вы используете оптимизацию с помощью «массива зависимостей», но неправильно указали какие-то зависимости. Например, если эффект передаёт вторым параметром `[]`, но при этом использует `someProp`, то он продолжит «видеть» исходное значение `someProp`. Правильным решением является либо исправление массива, либо отказ от его использования.
Наконец, возможна другая ситуация, почему вы видите устаревшие пропсы или состояние: когда вы используете оптимизацию с помощью «массива зависимостей», но неправильно указали какие-то зависимости. Например, если эффект передаёт вторым параметром `[]`, но при этом использует `someProp`, то он продолжит «видеть» исходное значение `someProp`. Правильным решением является либо исправление массива, либо отказ от его использования.
По этим ссылкам описаны [подходы к функциям](#is-it-safe-to-omit-functions-from-the-list-of-dependencies) в аналогичных ситуациях и [другие известные способы](#what-can-i-do-if-my-effect-dependencies-change-too-often) снижения частоты вызова эффектов, исключающие передачу неправильных зависимостей.

>Примечание
Expand Down Expand Up @@ -451,9 +452,62 @@ function ScrollView({row}) {

### Могу ли я изменить реф, переданный в функциональный компонент? {#can-i-make-a-ref-to-a-function-component}


Несмотря на то, что вам не понадобится это часто, вы можете предоставить некоторые императивные методы родительскому компоненту, используя хук [`useImperativeHandle`](/docs/hooks-reference.html#useimperativehandle).

### Как я могу измерить узел DOM? {#how-can-i-measure-a-dom-node}

Для определения положения или размера DOM-узла можно использовать [колбэк-реф](/docs/refs-and-the-dom.html#callback-refs). React будет вызывать этот колбэк всякий раз, когда реф привязывается к другому узлу. Вот [небольшая демонстрация](https://codesandbox.io/s/l7m0v5x4v9):

```js{4-8,12}
function MeasureExample() {
const [height, setHeight] = useState(0);

const measuredRef = useCallback(node => {
if (node !== null) {
setHeight(node.getBoundingClientRect().height);
}
}, []);

return (
<>
<h1 ref={measuredRef}>Привет, мир</h1>
<h2>Заголовок выше имеет высоту {Math.round(height)} пикселей</h2>
</>
);
}
```

Мы не выбрали `useRef` в этом примере, потому что объект рефа не уведомляет нас об *изменениях* текущего значения рефа. Использование колбэк-рефа гарантирует, что [даже если дочерний компонент отображает измеренный узел позже](https://codesandbox.io/s/818zzk8m78) (например, в ответ на клик), мы по-прежнему получаем уведомление об этом в родительском компоненте и можем обновлять измерения.

Обратите внимание, что мы передаем `[]` как массив зависимостей в `useCallback`. Это гарантирует, что наш колбэк-реф не изменится между повторными рендерами, а значит React не будет вызывать его без необходимости.

При желании вы можете [извлечь эту логику](https://codesandbox.io/s/m5o42082xy) в переиспользуемый хук:

```js{2}
function MeasureExample() {
const [rect, ref] = useClientRect();
return (
<>
<h1 ref={ref}>Привет, мир</h1>
{rect !== null &&
<h2>Заголовок выше имеет высоту {Math.round(height)} пикселей</h2>
}
</>
);
}

function useClientRect() {
const [rect, setRect] = useState(null);
const ref = useCallback(node => {
if (node !== null) {
setRect(node.getBoundingClientRect());
}
}, []);
return [rect, ref];
}
```


### Что значит `const [thing, setThing] = useState()`? {#what-does-const-thing-setthing--usestate-mean}

Если вы не знакомы с этим синтаксисом, ознакомьтесь с [объяснением](/docs/hooks-state.html#tip-what-do-square-brackets-mean) в документации хука состояния.
Expand Down Expand Up @@ -857,8 +911,8 @@ function Form() {
const [text, updateText] = useState('');
const textRef = useRef();

useLayoutEffect(() => {
textRef.current = text; // Записать в реф
useEffect(() => {
textRef.current = text; // Записать это в реф
});

const handleSubmit = useCallback(() => {
Expand Down Expand Up @@ -898,7 +952,7 @@ function useEventCallback(fn, dependencies) {
throw new Error('Невозможно вызвать обработчик события во время рендера.');
});

useLayoutEffect(() => {
useEffect(() => {
ref.current = fn;
}, [fn, ...dependencies]);

Expand Down
43 changes: 38 additions & 5 deletions content/docs/hooks-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ const [state, setState] = useState(() => {

Если вы обновите состояние хука тем же значением, что и текущее состояние, React досрочно выйдет из хука без повторного рендера дочерних элементов и запуска эффектов. (React использует [алгоритм сравнения `Object.is`](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).)

Обратите внимание, что для React всё еще может быть необходим повторный рендер этого компонента. Это не должно быть проблемой, потому что React не будет сильно «углубляться» в дерево. Если вы делаете дорогостоящие вычисления во время рендеринга, вы можете оптимизировать их с помощью `useMemo`.

### `useEffect` {#useeffect}

```js
Expand Down Expand Up @@ -171,12 +173,28 @@ useEffect(
### `useContext` {#usecontext}

```js
const context = useContext(Context);
const value = useContext(MyContext);
```

Принимает объект контекста (значение, возвращённое из `React.createContext`) и возвращает текущее значение контекста, как указано ближайшим поставщиком контекста для данного контекста.
Принимает объект контекста (значение, возвращаемое из `React.createContext`) и возвращает текущее значение контекста для этого контекста. Текущее значение контекста определяется пропом `value` ближайшего `<MyContext.Provider>` над вызывающим компонентом в дереве.

Когда ближайший `<MyContext.Provider>` над компонентом обновляется, этот хук вызовет повторный рендер с последним значением контекста, переданным этому провайдеру `MyContext`.

Запомните, аргумент для `useContext` должен быть *непосредственно сам объект контекста*:

* **Правильно:** `useContext(MyContext)`
* **Неправильно:** `useContext(MyContext.Consumer)`
* **Неправильно:** `useContext(MyContext.Provider)`


Когда провайдер обновляется, этот хук инициирует повторный рендер с последним значением контекста.
Компонент, вызывающий `useContext`, всегда будет перерендериваться при изменении значения контекста. Если повторный рендер компонента затратен, вы можете [оптимизировать его с помощью мемоизации](https://github.com/facebook/react/issues/15156#issuecomment-474590693).

>Совет
>

>Если вы были знакомы с API контекстов до появления хуков, то вызов `useContext(MyContext)` аналогичен выражению `static contextType = MyContext` в классе, либо компоненту `<MyContext.Provider>`.
>
>`useContext (MyContext)` позволяет только *читать* контекст и подписываться на его изменения. Вам всё ещё нужен `<MyContext.Provider>` выше в дереве, чтобы *предоставить* значение для этого контекста.

## Дополнительные хуки {#additional-hooks}

Expand Down Expand Up @@ -283,6 +301,8 @@ function Counter({initialCount}) {

Если вы вернёте то же значение из редюсера хука, что и текущее состояние, React выйдет без перерисовки дочерних элементов или запуска эффектов. (React использует [алгоритм сравнения Object.is](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).)

Обратите внимание, что для React всё еще может быть необходим повторный рендер этого компонента. Это не должно быть проблемой, потому что React не будет сильно «углубляться» в дерево. Если вы делаете дорогостоящие вычисления во время рендеринга, вы можете оптимизировать их с помощью `useMemo`.

### `useCallback` {#usecallback}

```js
Expand Down Expand Up @@ -354,7 +374,16 @@ function TextInputWithFocusButton() {
}
```

Обратите внимание, что `useRef()` полезен не только для атрибута `ref`. Он также [удобен для хранения любого изменяемого значения](/docs/hooks-faq.html#is-there-something-like-instance-variables) примерно так же, как вы используете поля экземпляров в классах.
По сути, `useRef` похож на «коробку», которая может содержать изменяемое значение в своём свойстве `.current`.

Возможно, вы знакомы с рефами в основном как со способом [получить доступ к DOM](/docs/refs-and-the-dom.html). Если вы передадите React объект рефа с помощью подобного выражения `<div ref={myRef}/>`, React установит собственное свойство `.current` на соответствующий DOM-узел при каждом его изменении.

Но хук `useRef()` полезен не только установкой атрибута с рефом. Он [удобен для сохранения любого мутируемого значения](/docs/hooks-faq.html#is-there-something-like-instance-variables), по аналогии с тем, как вы используете поля экземпляра в классах.

Это возможно, поскольку `useRef()` создаёт обычный JavaScript-объект. Единственная разница между `useRef()` и просто созданием самого объекта `{current: ...}` — это то, что хук `useRef` даст один и тот же объект с рефом при каждом рендере.

Имейте в виду, что `useRef` *не* уведомляет вас, когда изменяется его содержимое. Мутирование свойства `.current` не вызывает повторный рендер. Если вы хотите запустить некоторый код, когда React присоединяет или отсоединяет реф к узлу DOM, вы можете использовать [колбэк-реф](/docs/hooks-faq.html#how-can-i-measure-a-dom-node) вместо этого.


### `useImperativeHandle` {#useimperativehandle}

Expand Down Expand Up @@ -387,7 +416,11 @@ FancyInput = forwardRef(FancyInput);

> Совет
>
> Если вы переносите код из классового компонента, `useLayoutEffect` запускается в той же фазе, что и `componentDidMount` и `componentDidUpdate`, поэтому, если вы не уверены, какой хук эффект использовать, это, вероятно, наименее рискованно.
> Если вы переносите код из классового компонента, `useLayoutEffect` запускается в той же фазе, что и `componentDidMount` и `componentDidUpdate`. Тем не менее, *мы рекомендуем начать с `useEffect`**, и попробовать использовать `useLayoutEffect`, если тот приводит к возникновению проблем.
>
>Если вы используете серверный рендеринг, имейте в виду, что *ни* `useLayoutEffect`, ни `useEffect` не могут работать до загрузки JavaScript. Вот почему React предупреждает, когда серверный компонент содержит `useLayoutEffect`. Чтобы справиться с данной проблемой, либо переместите эту логику в `useEffect` (если она не нужна для первого рендера), либо задержите отображение этого компонента до тех пор, пока не выполнится рендеринг на стороне клиента (если HTML некорректный до запуска `useLayoutEffect`).
>
>Чтобы исключить компонент, который нуждается в эффектах макета из HTML-кода, полученного в результате серверного рендеринга, выполните его рендер по условию `showChild && <Child />` и отложите отображение с помощью `useEffect(() => { setShowChild(true); }, [])``. Таким образом, пользовательский интерфейс не будет выглядеть некорректно перед гидратацией.

### `useDebugValue` {#usedebugvalue}

Expand Down
13 changes: 11 additions & 2 deletions content/languages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,15 @@
- name: Italian
translated_name: Italiano
code: it
status: 0
status: 1
- name: Japanese
translated_name: 日本語
code: ja
status: 2
- name: Georgian
translated_name: ქართული
code: ka
status: 0
- name: Central Khmer
translated_name: ភាសាខ្មែរ
code: km
Expand Down Expand Up @@ -126,6 +130,7 @@
- name: Swedish
translated_name: Svenska
code: sv
status: 0
- name: Tamil
translated_name: தமிழ்
code: ta
Expand All @@ -134,6 +139,10 @@
translated_name: తెలుగు
code: te
status: 0
- name: Thai
translated_name: ไทย
code: th
status: 0
- name: Turkish
translated_name: Türkçe
code: tr
Expand All @@ -157,7 +166,7 @@
- name: Simplified Chinese
translated_name: 简体中文
code: zh-hans
status: 1
status: 2
- name: Traditional Chinese
translated_name: 繁體中文
code: zh-hant
Expand Down