diff --git a/content/docs/integrating-with-other-libraries.md b/content/docs/integrating-with-other-libraries.md
index 5bc8b2570..482e579cd 100644
--- a/content/docs/integrating-with-other-libraries.md
+++ b/content/docs/integrating-with-other-libraries.md
@@ -1,26 +1,26 @@
---
id: integrating-with-other-libraries
-title: Integrating with Other Libraries
+title: Взаимодействие со сторонними библиотеками
permalink: docs/integrating-with-other-libraries.html
---
-React can be used in any web application. It can be embedded in other applications and, with a little care, other applications can be embedded in React. This guide will examine some of the more common use cases, focusing on integration with [jQuery](https://jquery.com/) and [Backbone](https://backbonejs.org/), but the same ideas can be applied to integrating components with any existing code.
+React может использоваться в любом веб-приложении. Он может быть встроен в другие приложения, и, с некоторыми оговорками, другие приложения могут встраиваться в React. Это руководство рассматривает некоторые общие случаи, с упором на интеграцию с [jQuery](https://jquery.com/) и [Backbone](https://backbonejs.org). Те же подходы могут использоваться для интеграции компонентов с любым существующим кодом.
-## Integrating with DOM Manipulation Plugins {#integrating-with-dom-manipulation-plugins}
+## Интеграция с плагинами, изменяющими DOM {#integrating-with-dom-manipulation-plugins}
-React is unaware of changes made to the DOM outside of React. It determines updates based on its own internal representation, and if the same DOM nodes are manipulated by another library, React gets confused and has no way to recover.
+React не знает про изменения DOM, которые сделаны вне React. Он определяет обновления на основе своего внутреннего представления, и если одни и те же DOM-узлы управляются другими библиотеками, то это нарушает работу React без возможности её восстановления.
-This does not mean it is impossible or even necessarily difficult to combine React with other ways of affecting the DOM, you just have to be mindful of what each is doing.
+Это не означает, что соединить React с другими инструментами работы с DOM сложно или невозможно. Просто нужно помнить, за что отвечает каждый инструмент.
-The easiest way to avoid conflicts is to prevent the React component from updating. You can do this by rendering elements that React has no reason to update, like an empty `
`.
+Самый простой способ избежать конфликтов -- предотвратить обновление React-компонента. Это можно сделать через рендеринг элемента, который не должен обновляться React, например, пустой `
`.
-### How to Approach the Problem {#how-to-approach-the-problem}
+### Как решить проблему {#how-to-approach-the-problem}
-To demonstrate this, let's sketch out a wrapper for a generic jQuery plugin.
+Для демонстрации давайте набросаем обертку вокруг обобщенного jQuery-плагина.
-We will attach a [ref](/docs/refs-and-the-dom.html) to the root DOM element. Inside `componentDidMount`, we will get a reference to it so we can pass it to the jQuery plugin.
+Мы установим [реф](/docs/refs-and-the-dom.html) на корневой DOM-элемент. Внутри `componentDidMount` мы получим ссылку на этот реф и передадим её в jQuery-плагин.
-To prevent React from touching the DOM after mounting, we will return an empty `
` from the `render()` method. The `
` element has no properties or children, so React has no reason to update it, leaving the jQuery plugin free to manage that part of the DOM:
+Чтобы React не взаимодействовал с DOM после монтирования, вернём пустой `
` из метода `render()`. Элемент `
` не имеет ни свойств, ни дочерних компонентов, так что для React нет никаких причин его обновлять. Это даёт jQuery полную свободу управления этой частью DOM:
```js{3,4,8,12}
class SomePlugin extends React.Component {
@@ -39,37 +39,37 @@ class SomePlugin extends React.Component {
}
```
-Note that we defined both `componentDidMount` and `componentWillUnmount` [lifecycle methods](/docs/react-component.html#the-component-lifecycle). Many jQuery plugins attach event listeners to the DOM so it's important to detach them in `componentWillUnmount`. If the plugin does not provide a method for cleanup, you will probably have to provide your own, remembering to remove any event listeners the plugin registered to prevent memory leaks.
+Заметьте, что мы объявили два [метода жизненного цикла](/docs/react-component.html#the-component-lifecycle) — как `componentDidMount`, так и `componentWillUnmount`. Многие jQuery-плагины добавляют обработчики событий DOM, поэтому важно удалять их внутри `componentWillUnmount`. Если плагин не предоставляет метод для очистки, то, возможно, вам придётся написать свой. Помните об удалении обработчиков событий, добавленных плагином, чтобы избежать утечек памяти.
-### Integrating with jQuery Chosen Plugin {#integrating-with-jquery-chosen-plugin}
+### Интеграция с jQuery-плагином Chosen {#integrating-with-jquery-chosen-plugin}
-For a more concrete example of these concepts, let's write a minimal wrapper for the plugin [Chosen](https://harvesthq.github.io/chosen/), which augments `` inputs.
+Теперь рассмотрим конкретный пример. Давайте напишем минимальную обёртку для плагина [Chosen](https://harvesthq.github.io/chosen/), который работает с элементами ``.
->**Note:**
+>**Примечание:**
>
->Just because it's possible, doesn't mean that it's the best approach for React apps. We encourage you to use React components when you can. React components are easier to reuse in React applications, and often provide more control over their behavior and appearance.
+> То, что следующий способ работает, совсем не значит, что это оптимальное решение для React-приложений. Мы советуем пользоваться React-компонентами, когда это возможно. Они являются самым простым способом переиспользовать код в React-приложении, и часто дают больший контроль над своим поведением и внешним видом.
-First, let's look at what Chosen does to the DOM.
+Для начала, давайте посмотрим, что Chosen делает с DOM.
-If you call it on a `` DOM node, it reads the attributes off of the original DOM node, hides it with an inline style, and then appends a separate DOM node with its own visual representation right after the ``. Then it fires jQuery events to notify us about the changes.
+Когда вы вызываете его на DOM-узле ``, он читает атрибуты этого узла, скрывает его с помощью встроенных стилей и непосредственно перед ним добавляет отдельный DOM-узел с собственным визуальным представлением. Затем он запускает события jQuery, чтобы уведомлять нас об изменениях.
-Let's say that this is the API we're striving for with our `` wrapper React component:
+Допустим, мы хотим предоставить следующий API для нашего компонента-обёртки над ``:
```js
function Example() {
return (
console.log(value)}>
- vanilla
- chocolate
- strawberry
+ ваниль
+ шоколад
+ клубника
);
}
```
-We will implement it as an [uncontrolled component](/docs/uncontrolled-components.html) for simplicity.
+Для простоты мы будем реализовывать [неконтролируемый компонент](/docs/uncontrolled-components.html).
-First, we will create an empty component with a `render()` method where we return `` wrapped in a ``:
+Сначала создадим пустой компонент, с методом `render()`, который возвращает `
`, обёрнутый в ``:
```js{4,5}
class Chosen extends React.Component {
@@ -85,9 +85,9 @@ class Chosen extends React.Component {
}
```
-Notice how we wrapped `
` in an extra ``. This is necessary because Chosen will append another DOM element right after the `
` node we passed to it. However, as far as React is concerned, `` always only has a single child. This is how we ensure that React updates won't conflict with the extra DOM node appended by Chosen. It is important that if you modify the DOM outside of React flow, you must ensure React doesn't have a reason to touch those DOM nodes.
+Обратите внимание, что мы обернули `
` в дополнительный ``. Это нужно, потому что Chosen добавляет новый элемент сразу за узлом `
`, на котором он вызывается. Но React всегда ожидает только один дочерний элемент для ``. Так мы гарантируем, что обновления React не будут конфликтовать с дополнительным узлом, добавляемым Chosen. Если вы собираетесь изменять DOM вне React, важно убедиться, что React не взаимодействует с DOM-узлами.
-Next, we will implement the lifecycle methods. We need to initialize Chosen with the ref to the `
` node in `componentDidMount`, and tear it down in `componentWillUnmount`:
+Следующим шагом реализуем методы жизненного цикла. Нам нужно инициализировать Chosen с рефом на узле `` в `componentDidMount`, а затем убрать его в `componentWillUnmount`:
```js{2,3,7}
componentDidMount() {
@@ -100,17 +100,17 @@ componentWillUnmount() {
}
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/qmqeQx?editors=0010)
+[**Посмотреть на CodePen**](https://codepen.io/gaearon/pen/qmqeQx?editors=0010)
-Note that React assigns no special meaning to the `this.el` field. It only works because we have previously assigned this field from a `ref` in the `render()` method:
+Обратите внимание, что React не придаёт никакого особого значения полю `this.el`. Код работает потому, что ранее мы присвоили этому полю `ref` в методе `render()`:
```js
this.el = el}>
```
-This is enough to get our component to render, but we also want to be notified about the value changes. To do this, we will subscribe to the jQuery `change` event on the `` managed by Chosen.
+Этого достаточно, чтобы наш компонент отрендерился, но мы бы хотели получать уведомления об изменении значений. Для этого мы подпишемся на jQuery событие `change` на ``, контролируемом Chosen.
-We won't pass `this.props.onChange` directly to Chosen because component's props might change over time, and that includes event handlers. Instead, we will declare a `handleChange()` method that calls `this.props.onChange`, and subscribe it to the jQuery `change` event:
+Мы не станем передавать в Chosen `this.props.onChange` напрямую, потому что пропсы компонента могут со временем изменениться (в том числе и обработчики событий). Вместо этого мы объявим метод `handleChange()`, который будет вызывать `this.props.onChange`, и подпишем его на jQuery-событие `change`:
```js{5,6,10,14-16}
componentDidMount() {
@@ -131,11 +131,11 @@ handleChange(e) {
}
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/bWgbeE?editors=0010)
+[**Посмотреть на CodePen**](https://codepen.io/gaearon/pen/bWgbeE?editors=0010)
-Finally, there is one more thing left to do. In React, props can change over time. For example, the `` component can get different children if parent component's state changes. This means that at integration points it is important that we manually update the DOM in response to prop updates, since we no longer let React manage the DOM for us.
+В завершение осталось сделать ещё кое-что. В React пропсы могут изменяться со временем. Например, компонент `` может получать разные дочерние элементы, если состояние родительского компонента изменяется. Это означает, что в точке интеграции нам нужно вручную обновлять DOM, в соответствии с обновлениями проп, так как React больше не управляет DOM для нас.
-Chosen's documentation suggests that we can use jQuery `trigger()` API to notify it about changes to the original DOM element. We will let React take care of updating `this.props.children` inside ``, but we will also add a `componentDidUpdate()` lifecycle method that notifies Chosen about changes in the children list:
+Документация Chosen предлагает использовать jQuery-метод `trigger()`, чтобы сообщить об изменения в оригинальном DOM-элементе. Мы поручим React заниматься обновлением `this.props.children` внутри ``, но нужно добавить метод жизненного цикла `componentDidUpdate()`, чтобы уведомлять Chosen про обновление списка дочерних элементов:
```js{2,3}
componentDidUpdate(prevProps) {
@@ -145,9 +145,9 @@ componentDidUpdate(prevProps) {
}
```
-This way, Chosen will know to update its DOM element when the `` children managed by React change.
+Таким способом Chosen узнает, что нужно обновить его DOM-элемент, когда дочерние элементы `` были обновлены React.
-The complete implementation of the `Chosen` component looks like this:
+Полная реализация `Chosen` компонента выглядит так:
```js
class Chosen extends React.Component {
@@ -186,34 +186,34 @@ class Chosen extends React.Component {
}
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/xdgKOz?editors=0010)
+[**Посмотреть на CodePen**](https://codepen.io/gaearon/pen/xdgKOz?editors=0010)
-## Integrating with Other View Libraries {#integrating-with-other-view-libraries}
+## Интеграция с другими визульными библиотеками {#integrating-with-other-view-libraries}
-React can be embedded into other applications thanks to the flexibility of [`ReactDOM.render()`](/docs/react-dom.html#render).
+Благодаря гибкости [`ReactDOM.render()`](/docs/react-dom.html#render) React может встраиваться в другие приложения.
-Although React is commonly used at startup to load a single root React component into the DOM, `ReactDOM.render()` can also be called multiple times for independent parts of the UI which can be as small as a button, or as large as an app.
+Хотя обычно React используют для загрузки в DOM одного корневого компонента, `ReactDOM.render()` может быть вызван несколько раз для независимых частей UI. Это могут быть как отдельные кнопки, так и большие приложения.
-In fact, this is exactly how React is used at Facebook. This lets us write applications in React piece by piece, and combine them with our existing server-generated templates and other client-side code.
+На самом деле, именно так React используется в Facebook. Это позволяет писать приложения на React по частям и объединять их с существующими генерируемыми сервером шаблонами и другим клиентским кодом.
-### Replacing String-Based Rendering with React {#replacing-string-based-rendering-with-react}
+### Замена строковых шаблонов с помощью React {#replacing-string-based-rendering-with-react}
-A common pattern in older web applications is to describe chunks of the DOM as a string and insert it into the DOM like so: `$el.html(htmlString)`. These points in a codebase are perfect for introducing React. Just rewrite the string based rendering as a React component.
+Распространённый подход в старых веб-приложениях — описание частей DOM c помощью строк (вроде `${el.html(htmlString)`}). Такие участки кода прекрасно подходят для внедрения React. Просто переписываем рендеринг на основе строк в React-компонент.
-So the following jQuery implementation...
+Итак, есть текущая реализация на jQuery...
```js
-$('#container').html('Say Hello ');
+$('#container').html('Сказать «Привет» ');
$('#btn').click(function() {
- alert('Hello!');
+ alert('Привет!');
});
```
-...could be rewritten using a React component:
+...может быть переписана в React-компонент:
```js
function Button() {
- return Say Hello ;
+ return Сказать «Привет» ;
}
ReactDOM.render(
@@ -221,22 +221,22 @@ ReactDOM.render(
document.getElementById('container'),
function() {
$('#btn').click(function() {
- alert('Hello!');
+ alert('Привет!');
});
}
);
```
-From here you could start moving more logic into the component and begin adopting more common React practices. For example, in components it is best not to rely on IDs because the same component can be rendered multiple times. Instead, we will use the [React event system](/docs/handling-events.html) and register the click handler directly on the React `` element:
+А дальше вы можете начать переносить логику внутрь компонента и использовать остальные React-подходы. Например, в компонентах лучше не полагаться на идентификаторы, потому что один и тот же компонент может быть отрендерен несколько раз. Вместо этого мы используем [событийную систему React](/docs/handling-events.html) и зарегистрируем обработчик непосредственно на React-элементе ``:
```js{2,6,9}
function Button(props) {
- return Say Hello ;
+ return Сказать «Привет» ;
}
function HelloButton() {
function handleClick() {
- alert('Hello!');
+ alert('Привет!');
}
return ;
}
@@ -247,15 +247,15 @@ ReactDOM.render(
);
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/RVKbvW?editors=1010)
+[**Посмотреть на CodePen**](https://codepen.io/gaearon/pen/RVKbvW?editors=1010)
-You can have as many such isolated components as you like, and use `ReactDOM.render()` to render them to different DOM containers. Gradually, as you convert more of your app to React, you will be able to combine them into larger components, and move some of the `ReactDOM.render()` calls up the hierarchy.
+Вы можете завести столько изолированных компонентов, сколько вам захочется. И использовать `ReactDOM.render()` для рендеринга в разные DOM-контейнеры. Постепенно, по мере перевода вашего приложения на React, вы сможете комбинировать их в большие компоненты и переносить вызов `ReactDOM.render()` вверх по структуре.
-### Embedding React in a Backbone View {#embedding-react-in-a-backbone-view}
+### Встраиваем React в представления Backbone {#embedding-react-in-a-backbone-view}
-[Backbone](https://backbonejs.org/) views typically use HTML strings, or string-producing template functions, to create the content for their DOM elements. This process, too, can be replaced with rendering a React component.
+Представления в [Backbone](https://backbonejs.org/) обычно используют HTML-строки или функции, создающие строковые шаблоны для создания DOM элементов. Этот механизм также может быть заменен рендерингом React-компонентов.
-Below, we will create a Backbone view called `ParagraphView`. It will override Backbone's `render()` function to render a React `` component into the DOM element provided by Backbone (`this.el`). Here, too, we are using [`ReactDOM.render()`](/docs/react-dom.html#render):
+Ниже мы создадим Backbone-представление `ParagraphView`. Оно переопределит метод `render()` (из `Backbone.View`) для рендеринга React-компонента `` в DOM-элемент, предоставляемый Backbone (`this.el`). Также мы воспользуемся [`ReactDOM.render()`](/docs/react-dom.html#render):
```js{1,5,8,12}
function Paragraph(props) {
@@ -275,23 +275,23 @@ const ParagraphView = Backbone.View.extend({
});
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/gWgOYL?editors=0010)
+[**Посмотреть на CodePen**](https://codepen.io/gaearon/pen/gWgOYL?editors=0010)
-It is important that we also call `ReactDOM.unmountComponentAtNode()` in the `remove` method so that React unregisters event handlers and other resources associated with the component tree when it is detached.
+Стоит отметить вызов `ReactDOM.unmountComponentAtNode()` в методе `remove`. Он нужен для того, чтобы React отключил обработчики событий и другие ресурсы, связанные с деревом компонентов при удалении.
-When a component is removed *from within* a React tree, the cleanup is performed automatically, but because we are removing the entire tree by hand, we must call this method.
+Когда компонент удаляется из дерева React *изнутри*, очистка производится автоматически, но поскольку мы удаляем сущность из дерева вручную, то обязаны вызвать этот метод.
-## Integrating with Model Layers {#integrating-with-model-layers}
+## Интеграция со слоем моделей {#integrating-with-model-layers}
-While it is generally recommended to use unidirectional data flow such as [React state](/docs/lifting-state-up.html), [Flux](https://facebook.github.io/flux/), or [Redux](https://redux.js.org/), React components can use a model layer from other frameworks and libraries.
+Обычно рекомендуется использовать однонаправленный поток данных, вроде [состояния React](/docs/lifting-state-up.html), [Flux](https://facebook.github.io/flux/) или [Redux](https://redux.js.org/). Но React-компоненты могут также использовать слой данных из других библиотек и фреймворков.
-### Using Backbone Models in React Components {#using-backbone-models-in-react-components}
+### Использование моделей Backbone в React-компонентах {#using-backbone-models-in-react-components}
-The simplest way to consume [Backbone](https://backbonejs.org/) models and collections from a React component is to listen to the various change events and manually force an update.
+Самый простой способ использовать модели и коллекции [Backbone](https://backbonejs.org) из React-компонентов — это обработка различных событий и ручное обновление компонентов.
-Components responsible for rendering models would listen to `'change'` events, while components responsible for rendering collections would listen for `'add'` and `'remove'` events. In both cases, call [`this.forceUpdate()`](/docs/react-component.html#forceupdate) to rerender the component with the new data.
+Компоненты, отвечающие за рендеринг моделей, будут обрабатывать событие `'change'`, а компоненты, отвечающие за рендеринг коллекций, будут обрабатывать события `'add'` и `'remove'`. В обоих случаях для отображения новых данных нужно вызвать [`this.forceUpdate()`]](/docs/react-component.html#forceupdate).
-In the example below, the `List` component renders a Backbone collection, using the `Item` component to render individual items.
+В следующем примере компонент `list` ренедрит Backbone-коллекцию, используя компонент `Item` для рендеринга отдельных элементов.
```js{1,7-9,12,16,24,30-32,35,39,46}
class Item extends React.Component {
@@ -347,19 +347,19 @@ class List extends React.Component {
}
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/GmrREm?editors=0010)
+[**Посмотреть на CodePen**](https://codepen.io/gaearon/pen/GmrREm?editors=0010)
-### Extracting Data from Backbone Models {#extracting-data-from-backbone-models}
+### Вынос данных из моделей Backbone {#extracting-data-from-backbone-models}
-The approach above requires your React components to be aware of the Backbone models and collections. If you later plan to migrate to another data management solution, you might want to concentrate the knowledge about Backbone in as few parts of the code as possible.
+Подход, показанный выше, требует, чтобы ваши React-компоненты знали о наличии моделей и коллекций Backbone. Если у вас в планах есть переход на другое решение для управления данными, вы, возможно, захотите максимально уменьшить связь с Backbone.
-One solution to this is to extract the model's attributes as plain data whenever it changes, and keep this logic in a single place. The following is [a higher-order component](/docs/higher-order-components.html) that extracts all attributes of a Backbone model into state, passing the data to the wrapped component.
+Один из подходов — когда при каждом изменении модели, вы извлекаете её атрибуты в виде простых данных и храните всю логику в одном месте. Следующий [компонент высшего порядка](/docs/higher-order-components.html) извлекает все атрибуты Backbone-модели в `state`, передавая данные в оборачиваемый компонент.
-This way, only the higher-order component needs to know about Backbone model internals, and most components in the app can stay agnostic of Backbone.
+При этом подходе только компоненты высшего порядка будут знать о Backbone-моделях, а большая часть компонентов в приложении не будет завязана на Backbone.
-In the example below, we will make a copy of the model's attributes to form the initial state. We subscribe to the `change` event (and unsubscribe on unmounting), and when it happens, we update the state with the model's current attributes. Finally, we make sure that if the `model` prop itself changes, we don't forget to unsubscribe from the old model, and subscribe to the new one.
+В примере ниже, мы сделаем копию атрибутов модели для формирования начального состояния. Мы подпишемся на событие `change` (и отпишемся от него при удалении), и когда оно будет возникать, мы обновим состояние текущими атрибутами. Наконец, мы убедимся, что если изменяется сам проп `model`, мы не забываем отписаться от старой модели и подписаться на новую.
-Note that this example is not meant to be exhaustive with regards to working with Backbone, but it should give you an idea for how to approach this in a generic way:
+Обратите внимание, пример ниже не является полным в отношении работы с Backbone. Но он должен дать вам понимание общего подхода:
```js{1,5,10,14,16,17,22,26,32}
function connectToBackboneModel(WrappedComponent) {
@@ -399,7 +399,7 @@ function connectToBackboneModel(WrappedComponent) {
}
```
-To demonstrate how to use it, we will connect a `NameInput` React component to a Backbone model, and update its `firstName` attribute every time the input changes:
+Для демонстрации использования мы соединим React-компонент `NameInput` и Backbone-модель и будем обновлять её атрибут `firstName` при каждом изменении поля ввода:
```js{4,6,11,15,19-21}
function NameInput(props) {
@@ -407,7 +407,7 @@ function NameInput(props) {
- My name is {props.firstName}.
+ Моё имя - {props.firstName}.
);
}
@@ -434,6 +434,6 @@ ReactDOM.render(
);
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/PmWwwa?editors=0010)
+[**Посмотреть на CodePen**](https://codepen.io/gaearon/pen/PmWwwa?editors=0010)
-This technique is not limited to Backbone. You can use React with any model library by subscribing to its changes in the lifecycle methods and, optionally, copying the data into the local React state.
+Этот подход не ограничивается Backbone. Вы можете использовать React с любой библиотекой для работы с данными, просто подписываясь на методы жизненного цикла и, при необходимости, копируя данные во внутреннее состояние React.