Skip to content

Commit 9c6f689

Browse files
authored
Merge pull request #285 from reactjs/sync-1f2dbb7a
Sync with reactjs.org @ 1f2dbb7
2 parents 89da8d2 + ce39f1d commit 9c6f689

File tree

4 files changed

+113
-12
lines changed

4 files changed

+113
-12
lines changed

content/community/conferences.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ July 15-21, 2019. New York City, USA
5757

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

60+
### React Rally 2019
61+
August 22-23, 2019. Salt Lake City, USA.
62+
63+
[Website](https://www.reactrally.com/) - [Twitter](https://twitter.com/ReactRally) - [Instagram](https://www.instagram.com/reactrally/)
64+
6065
### ComponentsConf 2019 {#componentsconf-2019}
6166
September 6, 2019 in Melbourne, Australia
6267
[Website](https://www.componentsconf.com.au/) - [Twitter](https://twitter.com/componentsconf)

content/docs/hooks-faq.md

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ prev: hooks-reference.html
4141
* [Как я могу реализовать `getDerivedStateFromProps`?](#how-do-i-implement-getderivedstatefromprops)
4242
* [Существует что-нибудь наподобие forceUpdate?](#is-there-something-like-forceupdate)
4343
* [Могу ли я изменить реф, переданный в функциональный компонент?](#can-i-make-a-ref-to-a-function-component)
44+
* [Как я могу измерить узел DOM?](#how-can-i-measure-a-dom-node)
4445
* [Что значит `const [thing, setThing] = useState()`?](#what-does-const-thing-setthing--usestate-mean)
4546
* [Оптимизации производительности](#performance-optimizations)
4647
* [Могу ли я пропустить эффект при обновлениях?](#can-i-skip-an-effect-on-updates)
@@ -403,7 +404,7 @@ function Example() {
403404

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

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

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

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

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

457+
### Как я могу измерить узел DOM? {#how-can-i-measure-a-dom-node}
458+
459+
Для определения положения или размера DOM-узла можно использовать [колбэк-реф](/docs/refs-and-the-dom.html#callback-refs). React будет вызывать этот колбэк всякий раз, когда реф привязывается к другому узлу. Вот [небольшая демонстрация](https://codesandbox.io/s/l7m0v5x4v9):
460+
461+
```js{4-8,12}
462+
function MeasureExample() {
463+
const [height, setHeight] = useState(0);
464+
465+
const measuredRef = useCallback(node => {
466+
if (node !== null) {
467+
setHeight(node.getBoundingClientRect().height);
468+
}
469+
}, []);
470+
471+
return (
472+
<>
473+
<h1 ref={measuredRef}>Привет, мир</h1>
474+
<h2>Заголовок выше имеет высоту {Math.round(height)} пикселей</h2>
475+
</>
476+
);
477+
}
478+
```
479+
480+
Мы не выбрали `useRef` в этом примере, потому что объект рефа не уведомляет нас об *изменениях* текущего значения рефа. Использование колбэк-рефа гарантирует, что [даже если дочерний компонент отображает измеренный узел позже](https://codesandbox.io/s/818zzk8m78) (например, в ответ на клик), мы по-прежнему получаем уведомление об этом в родительском компоненте и можем обновлять измерения.
481+
482+
Обратите внимание, что мы передаем `[]` как массив зависимостей в `useCallback`. Это гарантирует, что наш колбэк-реф не изменится между повторными рендерами, а значит React не будет вызывать его без необходимости.
483+
484+
При желании вы можете [извлечь эту логику](https://codesandbox.io/s/m5o42082xy) в переиспользуемый хук:
485+
486+
```js{2}
487+
function MeasureExample() {
488+
const [rect, ref] = useClientRect();
489+
return (
490+
<>
491+
<h1 ref={ref}>Привет, мир</h1>
492+
{rect !== null &&
493+
<h2>Заголовок выше имеет высоту {Math.round(height)} пикселей</h2>
494+
}
495+
</>
496+
);
497+
}
498+
499+
function useClientRect() {
500+
const [rect, setRect] = useState(null);
501+
const ref = useCallback(node => {
502+
if (node !== null) {
503+
setRect(node.getBoundingClientRect());
504+
}
505+
}, []);
506+
return [rect, ref];
507+
}
508+
```
509+
510+
457511
### Что значит `const [thing, setThing] = useState()`? {#what-does-const-thing-setthing--usestate-mean}
458512

459513
Если вы не знакомы с этим синтаксисом, ознакомьтесь с [объяснением](/docs/hooks-state.html#tip-what-do-square-brackets-mean) в документации хука состояния.
@@ -857,8 +911,8 @@ function Form() {
857911
const [text, updateText] = useState('');
858912
const textRef = useRef();
859913
860-
useLayoutEffect(() => {
861-
textRef.current = text; // Записать в реф
914+
useEffect(() => {
915+
textRef.current = text; // Записать это в реф
862916
});
863917
864918
const handleSubmit = useCallback(() => {
@@ -898,7 +952,7 @@ function useEventCallback(fn, dependencies) {
898952
throw new Error('Невозможно вызвать обработчик события во время рендера.');
899953
});
900954
901-
useLayoutEffect(() => {
955+
useEffect(() => {
902956
ref.current = fn;
903957
}, [fn, ...dependencies]);
904958

content/docs/hooks-reference.md

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ const [state, setState] = useState(() => {
9696

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

99+
Обратите внимание, что для React всё еще может быть необходим повторный рендер этого компонента. Это не должно быть проблемой, потому что React не будет сильно «углубляться» в дерево. Если вы делаете дорогостоящие вычисления во время рендеринга, вы можете оптимизировать их с помощью `useMemo`.
100+
99101
### `useEffect` {#useeffect}
100102

101103
```js
@@ -171,12 +173,28 @@ useEffect(
171173
### `useContext` {#usecontext}
172174

173175
```js
174-
const context = useContext(Context);
176+
const value = useContext(MyContext);
175177
```
176178

177-
Принимает объект контекста (значение, возвращённое из `React.createContext`) и возвращает текущее значение контекста, как указано ближайшим поставщиком контекста для данного контекста.
179+
Принимает объект контекста (значение, возвращаемое из `React.createContext`) и возвращает текущее значение контекста для этого контекста. Текущее значение контекста определяется пропом `value` ближайшего `<MyContext.Provider>` над вызывающим компонентом в дереве.
180+
181+
Когда ближайший `<MyContext.Provider>` над компонентом обновляется, этот хук вызовет повторный рендер с последним значением контекста, переданным этому провайдеру `MyContext`.
182+
183+
Запомните, аргумент для `useContext` должен быть *непосредственно сам объект контекста*:
184+
185+
* **Правильно:** `useContext(MyContext)`
186+
* **Неправильно:** `useContext(MyContext.Consumer)`
187+
* **Неправильно:** `useContext(MyContext.Provider)`
188+
178189

179-
Когда провайдер обновляется, этот хук инициирует повторный рендер с последним значением контекста.
190+
Компонент, вызывающий `useContext`, всегда будет перерендериваться при изменении значения контекста. Если повторный рендер компонента затратен, вы можете [оптимизировать его с помощью мемоизации](https://github.com/facebook/react/issues/15156#issuecomment-474590693).
191+
192+
>Совет
193+
>
194+
195+
>Если вы были знакомы с API контекстов до появления хуков, то вызов `useContext(MyContext)` аналогичен выражению `static contextType = MyContext` в классе, либо компоненту `<MyContext.Provider>`.
196+
>
197+
>`useContext (MyContext)` позволяет только *читать* контекст и подписываться на его изменения. Вам всё ещё нужен `<MyContext.Provider>` выше в дереве, чтобы *предоставить* значение для этого контекста.
180198
181199
## Дополнительные хуки {#additional-hooks}
182200

@@ -283,6 +301,8 @@ function Counter({initialCount}) {
283301

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

304+
Обратите внимание, что для React всё еще может быть необходим повторный рендер этого компонента. Это не должно быть проблемой, потому что React не будет сильно «углубляться» в дерево. Если вы делаете дорогостоящие вычисления во время рендеринга, вы можете оптимизировать их с помощью `useMemo`.
305+
286306
### `useCallback` {#usecallback}
287307

288308
```js
@@ -354,7 +374,16 @@ function TextInputWithFocusButton() {
354374
}
355375
```
356376

357-
Обратите внимание, что `useRef()` полезен не только для атрибута `ref`. Он также [удобен для хранения любого изменяемого значения](/docs/hooks-faq.html#is-there-something-like-instance-variables) примерно так же, как вы используете поля экземпляров в классах.
377+
По сути, `useRef` похож на «коробку», которая может содержать изменяемое значение в своём свойстве `.current`.
378+
379+
Возможно, вы знакомы с рефами в основном как со способом [получить доступ к DOM](/docs/refs-and-the-dom.html). Если вы передадите React объект рефа с помощью подобного выражения `<div ref={myRef}/>`, React установит собственное свойство `.current` на соответствующий DOM-узел при каждом его изменении.
380+
381+
Но хук `useRef()` полезен не только установкой атрибута с рефом. Он [удобен для сохранения любого мутируемого значения](/docs/hooks-faq.html#is-there-something-like-instance-variables), по аналогии с тем, как вы используете поля экземпляра в классах.
382+
383+
Это возможно, поскольку `useRef()` создаёт обычный JavaScript-объект. Единственная разница между `useRef()` и просто созданием самого объекта `{current: ...}` — это то, что хук `useRef` даст один и тот же объект с рефом при каждом рендере.
384+
385+
Имейте в виду, что `useRef` *не* уведомляет вас, когда изменяется его содержимое. Мутирование свойства `.current` не вызывает повторный рендер. Если вы хотите запустить некоторый код, когда React присоединяет или отсоединяет реф к узлу DOM, вы можете использовать [колбэк-реф](/docs/hooks-faq.html#how-can-i-measure-a-dom-node) вместо этого.
386+
358387

359388
### `useImperativeHandle` {#useimperativehandle}
360389

@@ -387,7 +416,11 @@ FancyInput = forwardRef(FancyInput);
387416

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

content/languages.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,15 @@
6666
- name: Italian
6767
translated_name: Italiano
6868
code: it
69-
status: 0
69+
status: 1
7070
- name: Japanese
7171
translated_name: 日本語
7272
code: ja
7373
status: 2
74+
- name: Georgian
75+
translated_name: ქართული
76+
code: ka
77+
status: 0
7478
- name: Central Khmer
7579
translated_name: ភាសាខ្មែរ
7680
code: km
@@ -126,6 +130,7 @@
126130
- name: Swedish
127131
translated_name: Svenska
128132
code: sv
133+
status: 0
129134
- name: Tamil
130135
translated_name: தமிழ்
131136
code: ta
@@ -134,6 +139,10 @@
134139
translated_name: తెలుగు
135140
code: te
136141
status: 0
142+
- name: Thai
143+
translated_name: ไทย
144+
code: th
145+
status: 0
137146
- name: Turkish
138147
translated_name: Türkçe
139148
code: tr
@@ -157,7 +166,7 @@
157166
- name: Simplified Chinese
158167
translated_name: 简体中文
159168
code: zh-hans
160-
status: 1
169+
status: 2
161170
- name: Traditional Chinese
162171
translated_name: 繁體中文
163172
code: zh-hant

0 commit comments

Comments
 (0)