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 ``. ->**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 ``. Then it fires jQuery events to notify us about the changes. +Когда вы вызываете его на DOM-узле `` wrapped in a `
`: +Сначала создадим пустой компонент, с методом `render()`, который возвращает `` in an extra `
`. This is necessary because Chosen will append another DOM element right after the `` в дополнительный `
`. Это нужно, потому что Chosen добавляет новый элемент сразу за узлом `` node in `componentDidMount`, and tear it down in `componentWillUnmount`: +Следующим шагом реализуем методы жизненного цикла. Нам нужно инициализировать Chosen с рефом на узле ` 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 ``, контролируемом 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 ``, но нужно добавить метод жизненного цикла `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 `` были обновлены 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(''); +$('#container').html(''); $('#btn').click(function() { - alert('Hello!'); + alert('Привет!'); }); ``` -...could be rewritten using a React component: +...может быть переписана в React-компонент: ```js function Button() { - return ; + 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 `; + return ; } function HelloButton() { function handleClick() { - alert('Hello!'); + alert('Привет!'); } return