Skip to content

Commit bd10d98

Browse files
authored
Merge pull request #117 from reactjs/forwarding-refs
Translation Forwarding refs
2 parents 427554a + 7274209 commit bd10d98

File tree

7 files changed

+47
-48
lines changed

7 files changed

+47
-48
lines changed

content/docs/forwarding-refs.md

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,75 @@
11
---
22
id: forwarding-refs
3-
title: Forwarding Refs
3+
title: Перенаправление рефов
44
permalink: docs/forwarding-refs.html
55
---
66

7-
Ref forwarding is a technique for automatically passing a [ref](/docs/refs-and-the-dom.html) through a component to one of its children. This is typically not necessary for most components in the application. However, it can be useful for some kinds of components, especially in reusable component libraries. The most common scenarios are described below.
7+
Перенаправление рефов позволяет автоматически передавать [реф](/docs/refs-and-the-dom.html) компонента одному из его дочерних элементов. Большинству компонентов перенаправление рефов не нужно, но оно может быть полезно, например, если вы пишете библиотеку. Рассмотрим наиболее частые сценарии.
88

9-
## Forwarding refs to DOM components {#forwarding-refs-to-dom-components}
9+
## Перенаправление рефов в DOM-компоненты {#forwarding-refs-to-dom-components}
1010

11-
Consider a `FancyButton` component that renders the native `button` DOM element:
11+
Допустим, у нас есть компонент `FancyButton`, который рендерит нативный DOM-элемент `button`:
1212
`embed:forwarding-refs/fancy-button-simple.js`
1313

14-
React components hide their implementation details, including their rendered output. Other components using `FancyButton` **usually will not need to** [obtain a ref](/docs/refs-and-the-dom.html) to the inner `button` DOM element. This is good because it prevents components from relying on each other's DOM structure too much.
14+
React-компоненты скрывают свои детали реализации, в том числе результат рендеринга. Реф элемента `button` из `FancyButton` **обычно и не требуется** другим компонентам. Это хорошо, поскольку такой подход не даёт компонентам излишне полагаться на структуру DOM друг друга.
1515

16-
Although such encapsulation is desirable for application-level components like `FeedStory` or `Comment`, it can be inconvenient for highly reusable "leaf" components like `FancyButton` or `MyTextInput`. These components tend to be used throughout the application in a similar manner as a regular DOM `button` and `input`, and accessing their DOM nodes may be unavoidable for managing focus, selection, or animations.
16+
Такая инкапсуляция хорошо подходит компонентам, которые описывают некую законченную часть приложения, например, `FeedStory` или `Comment`. А вот в «маленьких», часто переиспользуемых компонентах, таких как `FancyButton` или `MyTextInput`, она может быть неудобной. Чтобы управлять фокусом, выделением и анимациями этих компонентов, придётся получить доступ к их DOM-узлам.
1717

18-
**Ref forwarding is an opt-in feature that lets some components take a `ref` they receive, and pass it further down (in other words, "forward" it) to a child.**
18+
**Перенаправление рефов позволяет взять `ref` из атрибутов компонента, и передать («перенаправить») его одному из дочерних компонентов.**
1919

20-
In the example below, `FancyButton` uses `React.forwardRef` to obtain the `ref` passed to it, and then forward it to the DOM `button` that it renders:
20+
В данном примере мы используем `React.forwardRef` в компоненте `FancyButton`, чтобы получить реф и передать его в дочерний DOM-элемент `button`.
2121

2222
`embed:forwarding-refs/fancy-button-simple-ref.js`
2323

24-
This way, components using `FancyButton` can get a ref to the underlying `button` DOM node and access it if necessary—just like if they used a DOM `button` directly.
24+
Таким образом, когда мы будем применять `FancyButton` в других компонентах, мы сможем получить реф находящегося в нём DOM-узла `button` и использовать его так же, как если бы мы рендерили непосредственно `button`.
2525

26-
Here is a step-by-step explanation of what happens in the above example:
26+
Рассмотрим этот пример пошагово:
2727

28-
1. We create a [React ref](/docs/refs-and-the-dom.html) by calling `React.createRef` and assign it to a `ref` variable.
29-
1. We pass our `ref` down to `<FancyButton ref={ref}>` by specifying it as a JSX attribute.
30-
1. React passes the `ref` to the `(props, ref) => ...` function inside `forwardRef` as a second argument.
31-
1. We forward this `ref` argument down to `<button ref={ref}>` by specifying it as a JSX attribute.
32-
1. When the ref is attached, `ref.current` will point to the `<button>` DOM node.
28+
1. Мы создаём [реф](/docs/refs-and-the-dom.html), вызвав `React.createRef` и записываем его в переменную `ref`.
29+
1. Мы передаём переменную `ref` в `<FancyButton ref={ref}>`, указывая её в JSX-атрибуте.
30+
1. React передаёт `ref` в функцию `(props, ref) => ...` внутри `forwardRef` в качестве второго аргумента.
31+
1. Мы передаём аргумент `ref` дальше в `<button ref={ref}>`, указывая его в JSX-атрибуте.
32+
1. После привязки рефа `ref.current` будет указывать на DOM-узел `<button>`.
3333

34-
>Note
34+
>Примечание
3535
>
36-
>The second `ref` argument only exists when you define a component with `React.forwardRef` call. Regular function or class components don't receive the `ref` argument, and ref is not available in props either.
36+
>Второй аргумент `ref` существует только в том случае, если вы создаёте компонент через функцию `React.forwardRef`. Обычные функциональные или классовые компоненты не получают `ref` в качестве аргумента или пропа.
3737
>
38-
>Ref forwarding is not limited to DOM components. You can forward refs to class component instances, too.
38+
>Перенаправить реф можно не только в DOM-компонент, но и в экземпляр классового компонента.
3939
40-
## Note for component library maintainers {#note-for-component-library-maintainers}
40+
## Примечание для разработчиков библиотек компонентов {#note-for-component-library-maintainers}
4141

42-
**When you start using `forwardRef` in a component library, you should treat it as a breaking change and release a new major version of your library.** This is because your library likely has an observably different behavior (such as what refs get assigned to, and what types are exported), and this can break apps and other libraries that depend on the old behavior.
42+
**Если вы впервые использовали `forwardRef` в компоненте библиотеки, то следует сделать новую версию мажорной и указать на обратную несовместимость изменений.** Причина этого в том, что, скорее всего, компонент станет вести себя заметно иначе (например, изменится тип экспортируемых данных и элемент, к которому привязан реф), в результате чего приложения и другие библиотеки, полагающиеся на старое поведение, перестанут работать.
4343

44-
Conditionally applying `React.forwardRef` when it exists is also not recommended for the same reasons: it changes how your library behaves and can break your users' apps when they upgrade React itself.
44+
По этой же причине мы рекомендуем не вызывать `React.forwardRef` условно (то есть сперва проверяя, что эта функция определена). Это изменит поведение вашей библиотеки и приложения ваших пользователей могут перестать работать при обновлении самого React.
45+
## Перенаправление рефов в компонентах высшего порядка {#forwarding-refs-in-higher-order-components}
4546

46-
## Forwarding refs in higher-order components {#forwarding-refs-in-higher-order-components}
47-
48-
This technique can also be particularly useful with [higher-order components](/docs/higher-order-components.html) (also known as HOCs). Let's start with an example HOC that logs component props to the console:
47+
Особенно полезным перенаправление может оказаться в [компонентах высшего порядка](/docs/higher-order-components.html) (также известных как HOC). Начнём с примера, в котором HOC выводит пропсы компонента в консоль:
4948
`embed:forwarding-refs/log-props-before.js`
5049

51-
The "logProps" HOC passes all `props` through to the component it wraps, so the rendered output will be the same. For example, we can use this HOC to log all props that get passed to our "fancy button" component:
50+
Компонент высшего порядка `logProps` передаёт все пропсы в компонент, который он оборачивает, так что рендерить они будут одно и то же. С его помощью мы будем выводить в консоль все пропсы, переданные в наш компонент с кнопкой:
5251
`embed:forwarding-refs/fancy-button.js`
5352

54-
There is one caveat to the above example: refs will not get passed through. That's because `ref` is not a prop. Like `key`, it's handled differently by React. If you add a ref to a HOC, the ref will refer to the outermost container component, not the wrapped component.
53+
Обратите внимание, что в этом примере не будут передаваться рефы. Так происходит, потому что `ref` это не проп. Подобно `key`, React обрабатывает `ref` особым образом. Если вы укажите реф для HOC, он привяжется к ближайшему к корню контейнера, а не к переданному в HOC компоненту.
5554

56-
This means that refs intended for our `FancyButton` component will actually be attached to the `LogProps` component:
55+
Следовательно, рефы, предназначенные для компонента `FancyButton`, окажутся привязанными к компоненту `LogProps`:
5756
`embed:forwarding-refs/fancy-button-ref.js`
5857

59-
Fortunately, we can explicitly forward refs to the inner `FancyButton` component using the `React.forwardRef` API. `React.forwardRef` accepts a render function that receives `props` and `ref` parameters and returns a React node. For example:
58+
К счастью, мы можем явно перенаправить рефы на компонент `FancyButton` внутри HOC при помощи API `React.forwardRef`. В `React.forwardRef` передаётся функция рендеринга, которая принимает аргументы `props` и `ref`, а возвращает узел React. Например:
6059
`embed:forwarding-refs/log-props-after.js`
6160

62-
## Displaying a custom name in DevTools {#displaying-a-custom-name-in-devtools}
61+
## Изменение названия в инструментах разработки {#displaying-a-custom-name-in-devtools}
6362

64-
`React.forwardRef` accepts a render function. React DevTools uses this function to determine what to display for the ref forwarding component.
63+
В `React.forwardRef` передаётся функция рендеринга. Эта функция определяет, как будет называться компонент в инструментах разработки.
6564

66-
For example, the following component will appear as "*ForwardRef*" in the DevTools:
65+
Например, вот этот компонент будет называться «*ForwardRef*»:
6766

6867
`embed:forwarding-refs/wrapped-component.js`
6968

70-
If you name the render function, DevTools will also include its name (e.g. "*ForwardRef(myFunction)*"):
69+
Если присвоить имя функции рендеринга, то оно появится в названии компонента в инструментах разработки (например, «*ForwardRef(myFunction)*»):
7170

7271
`embed:forwarding-refs/wrapped-component-with-function-name.js`
7372

74-
You can even set the function's `displayName` property to include the component you're wrapping:
73+
Можно даже назначить функции свойство `displayName` и указать в нём, какой именно компонент обёрнут в HOC:
7574

7675
`embed:forwarding-refs/customized-display-name.js`

examples/forwarding-refs/customized-display-name.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ function logProps(Component) {
77
return <LogProps {...props} forwardedRef={ref} />;
88
}
99

10-
// Give this component a more helpful display name in DevTools.
11-
// e.g. "ForwardRef(logProps(MyComponent))"
10+
// Дадим компоненту более понятное имя в инструментах разработки.
11+
// Например, "ForwardRef(logProps(MyComponent))"
1212
// highlight-range{1-2}
1313
const name = Component.displayName || Component.name;
1414
forwardRef.displayName = `logProps(${name})`;

examples/forwarding-refs/fancy-button-ref.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import FancyButton from './FancyButton';
33
// highlight-next-line
44
const ref = React.createRef();
55

6-
// The FancyButton component we imported is the LogProps HOC.
7-
// Even though the rendered output will be the same,
8-
// Our ref will point to LogProps instead of the inner FancyButton component!
9-
// This means we can't call e.g. ref.current.focus()
6+
// Компонент FancyButton, который мы импортировали — это HOC LogProps.
7+
// Несмотря на то, что рендерят они одно и то же,
8+
// реф в данном случае будет указывать на LogProps, а не на сам FancyButton!
9+
// Это значит, что мы не сможем, например, вызвать ref.current.focus()
1010
// highlight-range{4}
1111
<FancyButton
1212
label="Click Me"

examples/forwarding-refs/fancy-button-simple-ref.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ const FancyButton = React.forwardRef((props, ref) => (
55
</button>
66
));
77

8-
// You can now get a ref directly to the DOM button:
8+
// Теперь реф будет указывать непосредственно на DOM-узел button:
99
const ref = React.createRef();
1010
<FancyButton ref={ref}>Click me!</FancyButton>;

examples/forwarding-refs/fancy-button.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class FancyButton extends React.Component {
66
// ...
77
}
88

9-
// Rather than exporting FancyButton, we export LogProps.
10-
// It will render a FancyButton though.
9+
// Вместо экспорта FancyButton, мы экспортируем LogProps.
10+
// Рендериться при этом будет FancyButton.
1111
// highlight-next-line
1212
export default logProps(FancyButton);

examples/forwarding-refs/log-props-after.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ function logProps(Component) {
99
// highlight-next-line
1010
const {forwardedRef, ...rest} = this.props;
1111

12-
// Assign the custom prop "forwardedRef" as a ref
12+
// Передаём в качестве рефа проп "forwardedRef"
1313
// highlight-next-line
1414
return <Component ref={forwardedRef} {...rest} />;
1515
}
1616
}
1717

18-
// Note the second param "ref" provided by React.forwardRef.
19-
// We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
20-
// And it can then be attached to the Component.
18+
// Обратите внимание, что React.forwardRef передает "ref" вторым аргументом.
19+
// Мы можем передать его дальше как проп, например, "forwardedRef",
20+
// а потом привязать его к компоненту.
2121
// highlight-range{1-3}
2222
return React.forwardRef((props, ref) => {
2323
return <LogProps {...props} forwardedRef={ref} />;

examples/forwarding-refs/log-props-before.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
function logProps(WrappedComponent) {
33
class LogProps extends React.Component {
44
componentDidUpdate(prevProps) {
5-
console.log('old props:', prevProps);
6-
console.log('new props:', this.props);
5+
console.log('старые пропсы:', prevProps);
6+
console.log('новые пропсы:', this.props);
77
}
88

99
render() {

0 commit comments

Comments
 (0)