Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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 будет вызывать этот колбэк всякий раз, когда ref подключается к другому узлу. Вот [небольшая демонстрация](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}>Hello, world</h1>
{rect !== null &&
<h2>The above header is {Math.round(rect.height)}px tall</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).)

Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `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` должен быть самим объектом *context*:

* **Правильно:** `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).)

Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `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). Если вы передадите объект рефа для реакции с `<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