Используем портал из React 16, чтобы сделать что-то классное

Hydrock
Front Stories
Published in
3 min readNov 23, 2017

React 16 уже доступен, и одним из наиболее интересных нововведений являются «Порталы».

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

Но это не очень интересно. Давайте сделаем кое что странное…

Поскольку портал, просто берет элемент и добавляет его в какой-то другой элемент, вы можете не ограничиваться вставкой в текущем документе. Вы можете добавить его в тело совершенно другого документа, возможно, в документ в совершенно другом окне.

Ниже у меня есть базовая страница (слева), у которой есть счетчик с кнопкой, а также окно (справа), входящее в одно и то же приложение React.

Тот факт, что окно справа – это одно и то же приложение React, – это то, что должно вас сейчас волновать.

Вы можете поверить на слово, что цифры растут синхронно, или откройте пример

Все, что вы видите на картинке выше, находится в одном компоненте.

Вы наверняка уже рассмотрели, что <MyWindowPortal> немного особенный, и все, что находится внутри него, будет отображаться в другом окне.

Вы правы, и я горжусь вами. В частности, <MyWindowPortal> выполняет две функции:

  1. Открывает новое окно браузера, когда оно монтируется
  2. Создает «портал» и добавляет реквизиты в тело нового окна.

Разве это не самая крутая вещь?

Я так взволнован, что мне нужно прогуляться.

Я видел утку!

Ниже расположено тело компонента показанного выше. Часть, которая является новой в React 16, представляет собой ReactDOM.createPortal на строке 11 — вот где происходит волшебство.

Приношу извинения за то, что методы жизненного цикла в странном поряд

Имеет ли это смысл? Компонент ничего не возвращает, но он делает что-то в другом месте.

Может быть, еще один способ подумать об этом: обычно родительский компонент говорит дочернему компоненту: «эй, отрисуй такой-то DOM, а потом верни мне результаты», идочерний компонент делает то, что ему говорят. Но в нашем случае дочерний элемент говорит: «Нет! Я собираюсь показать материал в другом окне и написать сообщение в блоге об этом! “

Теперь я знаю, о чем вы думаете.

У вас пересохло в горле от волнения и хотите пить. Да, пойдите, уталите жажду.

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

Ну, хорошие новости, все возможно!

Сначала я надеялся, что будет простой способ скопировать стили в новое окно. Затем я вспомнил, что моя жизнь — это не что иное, как серия бессмысленных заданий, чтобы заполнить минуты и часы, их единственная цель — отвлечь меня от глубокой, воющей пустоты внутри.

Так что написать функцию было весело!

Вот она:

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

Теперь я могу скопировать стили сразу после открытия нового окна:

Вот готовый пример на codepen:

Я не думаю, что это будет работать из приложения Medium на iOS / Android, поэтому нажмите значок codepen в правом верхнем углу, чтобы открыть его в браузере.

Я думаю, что это конец поста.

Всем пока!

--

--