кодесурса
«Реагировать

Интеграция с другими библиотеками

script1adsense2code
script1adsense3code

React можно использовать в любом веб-приложении. Он может быть встроен в другие приложения, и с небольшой осторожностью другие приложения могут быть встроены в React. В этом руководстве будут рассмотрены некоторые из наиболее распространенных вариантов использования с упором на интеграцию с jQuery и Backbone, но те же идеи могут быть применены к интеграции компонентов с любым существующим кодом.

Интеграция с плагинами DOM Manipulation

React не знает об изменениях, внесенных в DOM вне React. Он определяет обновления на основе своего собственного внутреннего представления, и если те же узлы DOM управляются другой библиотекой, React запутывается и не имеет возможности для восстановления.

Это не означает, что невозможно или даже необязательно сложно сочетать React с другими способами воздействия на DOM, вы просто должны помнить о том, что каждый из них делает.

Самый простой способ избежать конфликтов - это предотвратить обновление компонента React. Вы можете сделать это, отображая элементы, которые React не имеет оснований для обновления, например пустой <div />.

Как подойти к проблеме

Чтобы продемонстрировать это, давайте наметим обертку для универсального плагина jQuery.

Мы прикрепим ссылку к корневому элементу DOM. Внутри componentDidMount мы получим ссылку на него, чтобы мы могли передать его плагину jQuery.

Чтобы React не касался DOM после монтирования, мы вернем пустой <div /> из метода render (). Элемент <div /> не имеет свойств или дочерних элементов, поэтому у React нет оснований для его обновления, в результате чего плагин jQuery может свободно управлять этой частью DOM:

class SomePlugin extends React.Component {
  componentDidMount() {
    this.$el = $(this.el);
    this.$el.somePlugin();
  }
  componentWillUnmount() {
    this.$el.somePlugin('destroy');
  }
  render() {
    return <div ref={el => this.el = el} />;
  }
}

Обратите внимание, что мы определили методы жизненного цикла componentDidMount и componentWillUnmount. Многие плагины jQuery присоединяют прослушиватели событий к DOM, поэтому важно отключить их в componentWillUnmount. Если плагин не предоставляет метод для очистки, вам, вероятно, придется предоставить свой собственный, не забывая удалить любые прослушиватели событий, которые зарегистрировал плагин, чтобы предотвратить утечки памяти.

Интеграция с плагином jQuery Chosen

Для более конкретного примера этих концепций давайте напишем минимальную оболочку для плагина Chosen, которая дополняет входные данные <select>.

Замечания:

То, что это возможно, не означает, что это лучший подход для приложений React. Рекомендуется использовать компоненты React, когда это возможно. Компоненты React легче повторно использовать в приложениях React, и они часто обеспечивают больший контроль над их поведением и внешним видом.

Во-первых, давайте посмотрим, что Chosen делает с DOM.

Если вы вызываете его на узле DOM <select>, он считывает атрибуты с исходного узла DOM, скрывает его с помощью встроенного стиля, а затем добавляет отдельный узел DOM со своим собственным визуальным представлением сразу после <select>. Затем он запускает события jQuery, чтобы уведомить нас об изменениях.

Допустим, это API, к которому мы стремимся с помощью нашего <Resen> оберточного компонента React:

function Example() {
  return (
    <Chosen onChange={value => console.log(value)}>
      <option>vanilla</option>
      <option>chocolate</option>
      <option>strawberry</option>
    </Chosen>
  );
}

Мы будем реализовывать его как неконтролируемый компонент для простоты.

Сначала мы создадим пустой компонент с методом render (), в который мы вернем <select>, заключенный в <div>:

class Chosen extends React.Component {
  render() {
    return (
      <div>
        <select className="Chosen-select" ref={el => this.el = el}>
          {this.props.children}
        </select>
      </div>
    );
  }
}

Обратите внимание, как мы завернули <select> в дополнительный <div>. Это необходимо, потому что Chosen добавит другой элемент DOM сразу после узла <select>, который мы передали ему. Однако, что касается React, у <div> всегда есть только один ребенок. Таким образом мы гарантируем, что обновления React не будут конфликтовать с дополнительным узлом DOM, добавленным Chosen. Важно, что если вы изменяете DOM вне потока React, вы должны убедиться, что у React нет причин касаться этих узлов DOM.

Далее мы реализуем методы жизненного цикла. Нам нужно инициализировать Chosen с помощью ссылки на узел <select> в componentDidMount и разорвать его в componentWillUnmount:

componentDidMount() {
  this.$el = $(this.el);
  this.$el.chosen();
}
componentWillUnmount() {
  this.$el.chosen('destroy');
}

Обратите внимание, что React не придает особого значения полю this.el. Это работает только потому, что мы ранее присвоили это поле из ссылки в методе render ():

<select className="Chosen-select" ref={el => this.el = el}>

Этого достаточно для визуализации нашего компонента, но мы также хотим получать уведомления об изменениях значения. Для этого мы подпишемся на событие изменения jQuery в <select>, управляемом Chosen.

Мы не будем передавать this.props.onChange напрямую в Chosen, поскольку реквизиты компонента могут со временем меняться, включая обработчики событий. Вместо этого мы объявим метод handleChange (), который вызывает this.props.onChange, и подпишем его на событие изменения jQuery:

componentDidMount() {
  this.$el = $(this.el);
  this.$el.chosen();
  this.handleChange = this.handleChange.bind(this);
  this.$el.on('change', this.handleChange);
}
componentWillUnmount() {
  this.$el.off('change', this.handleChange);
  this.$el.chosen('destroy');
}
handleChange(e) {
  this.props.onChange(e.target.value);
}

Наконец, осталось сделать еще одну вещь. В React реквизиты могут меняться со временем. Например, компонент <Chosen> может получить разные дочерние элементы, если состояние родительского компонента изменяется. Это означает, что в точках интеграции важно, чтобы мы вручную обновляли DOM в ответ на обновления поддержки, поскольку мы больше не позволяем React управлять DOM за нас.

Документация Chosen предполагает, что мы можем использовать jQuery trigger () API, чтобы уведомлять его об изменениях исходного элемента DOM. Мы позволим React позаботиться об обновлении this.props.children внутри <select>, но мы также добавим метод жизненного цикла componentDidUpdate (), который уведомляет Chosen об изменениях в списке детей:

componentDidUpdate(prevProps) {
  if (prevProps.children !== this.props.children) {
    this.$el.trigger("chosen:updated");
  }
}

Таким образом, Chosen будет знать, как обновить свой элемент DOM, когда дочерние элементы <select>, управляемые React, изменятся.

Полная реализация компонента Chosen выглядит следующим образом:

class Chosen extends React.Component {
  componentDidMount() {
    this.$el = $(this.el);
    this.$el.chosen();
    this.handleChange = this.handleChange.bind(this);
    this.$el.on('change', this.handleChange);
  }
  
  componentDidUpdate(prevProps) {
    if (prevProps.children !== this.props.children) {
      this.$el.trigger("chosen:updated");
    }
  }
  componentWillUnmount() {
    this.$el.off('change', this.handleChange);
    this.$el.chosen('destroy');
  }
  
  handleChange(e) {
    this.props.onChange(e.target.value);
  }
  render() {
    return (
      <div>
        <select className="Chosen-select" ref={el => this.el = el}>
          {this.props.children}
        </select>
      </div>
    );
  }
}

Новый контент: Composer: менеджер зависимостей для PHP , R программирования


script1adsense4code
script1adsense5code
disqus2code
script1adsense6code
script1adsense7code
script1adsense8code
buysellads2code