3.14 Веб-компоненты

React и Web Components созданы для решения разных проблем. Веб-компоненты обеспечивают надежную инкапсуляцию для повторно используемых компонентов, в то время как React предоставляет декларативную библиотеку, которая поддерживает DOM в синхронизации с вашими данными. Эти две цели являются взаимодополняющими. Как разработчик, вы можете использовать React в своих веб-компонентах или использовать веб-компоненты в React или и то и то.

Большинство использующих React не используют веб-компоненты, но вы, возможно, захотите, особенно если вы используете сторонние компоненты пользовательского интерфейса, которые написаны с использованием веб-компонентов.


3.14.1 Использование веб-компонентов в React


Код
    
  class Modal extends React.Component {
    render() {
      return <brick-layout flex>{this.props.content}</brick-layout>;
    }
  }
  


Внимание!

Веб-компоненты часто предоставляют необходимое API. Например, веб-компонент video может предоставлять функции play() и pause(). Чтобы получить доступ к необходимым API веб-компонента, вам нужно будет использовать ссылку для непосредственного взаимодействия с узлом DOM. Если вы используете сторонние веб-компоненты, лучшим решением является написание компонента React, который является оболочкой веб-компонента. События, эмитированные веб-компонентом, могут неправильно распространяться через отрисовываемое React-ом дерево. Вам нужно будет самим добавить обработчики для этих событий в ваши компоненты React.

Существует распространённая путаница, заключающаяся в том, что веб-компоненты используют class вместо className.


Код
    
  function BrickMenu() {
    return (
    <brick-menu class="menu">
      <brick-item selected>Item 1</brick-item>
      <brick-item>Item 2</brick-item>
      <brick-item>Item 3</brick-item>
      <brick-item>Item 4</brick-item>
    </brick-menu>
    );
  }
  


3.14.2 Использование React в веб-компонентах


Код
    
  class XSearch extends HTMLElement {
    connectedCallback() {
      const mountPoint = document.createElement('span');
      this.attachShadow({ mode: 'open' }).appendChild(mountPoint);
  
      const name = this.getAttribute('name');
      const url = 'https://www.google.com/search?q=' + encodeURIComponent(name);
      ReactDOM.render(<a href={url}>{name}</a>, mountPoint);
    }
  }
  customElements.define('x-search', XSearch);
  


Внимание!

Этот код не будет работать, если вы трансформируете классы с помощью Babel. См. данную проблему . Включите custom-elements-es5-adapter, прежде чем загружать веб-компоненты, чтобы исправить эту проблему.