Перейти к содержанию

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

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

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

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

1
2
3
4
5
6
7
8
9
class HelloMessage extends React.Component {
  render() {
    return (
      <div>
        Привет, <x-search>{this.props.name}</x-search>!
      </div>
    )
  }
}

Примечание:

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

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

Веб-компоненты используют «class» вместо «className», что часто вводит людей в замешательство.

1
2
3
4
5
6
7
8
function BrickFlipbox() {
  return (
    <brick-flipbox class="demo">
      <div>Передняя сторона</div>
      <div>Обратная сторона</div>
    </brick-flipbox>
  )
}

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
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 перед загрузкой веб-компонентов, чтобы решить эту проблему.

Комментарии