Реагировать на порталы

Узнайте, как использовать React Portals

React 16, выпущенный в сентябре 2017 года, представил Portals.

Портал - это способ визуализировать элемент за пределами его иерархии компонентов в отдельном компоненте.

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

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

React предлагает простой API для этого,ReactDOM.createPortal(), который принимает 2 аргумента. Первый - это элемент для рендеринга, второй - это элемент DOM, из которого его нужно рендерить.

Классический вариант использования - модальные окна.

Модальное окно для рендеринга в полноэкранном режиме должно находиться вне элемента, чтобы его можно было правильно стилизовать с помощью CSS.

Итак, если модальное окно определено как компонент:

class Modal extends React.Component {
  constructor(props) {
    super(props)
    this.el = document.createElement('div')
  }

componentDidMount() { document.getElementById(‘modal’).appendChild(this.el) }

componentWillUnmount() { document.getElementById(‘modal’).removeChild(this.el) }

render() { return ReactDOM.createPortal( this.props.children, this.el ) } }

Мы можем сделать так, чтобы компонент приложения отображал его, и все события, происходящие в модальном компоненте, будут обрабатываться приложением, даже если технически модальный элемент отображается в другом дереве DOM:

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {showModal: false}
<span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">handleShow</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">handleShow</span>.<span style="color:#a6e22e">bind</span>(<span style="color:#66d9ef">this</span>)
<span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">handleHide</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">handleHide</span>.<span style="color:#a6e22e">bind</span>(<span style="color:#66d9ef">this</span>)

}

handleShow() { this.setState({showModal: true}) }

handleHide() { this.setState({showModal: false}) }

render() { const modal = this.state.showModal ? ( <Modal> <div> The modal <button onClick={this.handleHide}>Hide</button> </div> </Modal> ) : ‘’

<span style="color:#66d9ef">return</span> (
  <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
    <span style="color:#a6e22e">The</span> <span style="color:#a6e22e">app</span> <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">button</span> <span style="color:#a6e22e">onClick</span><span style="color:#f92672">=</span>{<span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">handleShow</span>}<span style="color:#f92672">&gt;</span><span style="color:#a6e22e">Show</span> <span style="color:#a6e22e">modal</span><span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/button&gt;</span>
    {<span style="color:#a6e22e">modal</span>}
  <span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/div&gt;</span>
)

} }

ReactDOM.render(<App />, document.getElementById(‘app’))

См. Полный пример наhttps://codepen.io/flaviocopes/pen/KbdagX

Скачать мою бесплатнуюСправочник по React


Больше руководств по реакции: