Используем портал из React 16, чтобы сделать что-то классное
React 16 уже доступен, и одним из наиболее интересных нововведений являются «Порталы».
Порталы позволяют создавать DOM узлы за пределами родительского компонента, оставаясь под контролем React. В документации объясняют это красиво, используя пример модального окна. Это хорошо работает и для всплывающих подсказок тоже (вот что я сделал ранее).
Но это не очень интересно. Давайте сделаем кое что странное…
Поскольку портал, просто берет элемент и добавляет его в какой-то другой элемент, вы можете не ограничиваться вставкой в текущем документе. Вы можете добавить его в тело совершенно другого документа, возможно, в документ в совершенно другом окне.
Ниже у меня есть базовая страница (слева), у которой есть счетчик с кнопкой, а также окно (справа), входящее в одно и то же приложение React.
Тот факт, что окно справа – это одно и то же приложение React, – это то, что должно вас сейчас волновать.
Все, что вы видите на картинке выше, находится в одном компоненте.
Вы наверняка уже рассмотрели, что <MyWindowPortal>
немного особенный, и все, что находится внутри него, будет отображаться в другом окне.
Вы правы, и я горжусь вами. В частности, <MyWindowPortal>
выполняет две функции:
- Открывает новое окно браузера, когда оно монтируется
- Создает «портал» и добавляет реквизиты в тело нового окна.
Разве это не самая крутая вещь?
Я так взволнован, что мне нужно прогуляться.
Я видел утку!
Ниже расположено тело компонента показанного выше. Часть, которая является новой в React 16, представляет собой ReactDOM.createPortal
на строке 11 — вот где происходит волшебство.
Имеет ли это смысл? Компонент ничего не возвращает, но он делает что-то в другом месте.
Может быть, еще один способ подумать об этом: обычно родительский компонент говорит дочернему компоненту: «эй, отрисуй такой-то DOM, а потом верни мне результаты», идочерний компонент делает то, что ему говорят. Но в нашем случае дочерний элемент говорит: «Нет! Я собираюсь показать материал в другом окне и написать сообщение в блоге об этом! “
Теперь я знаю, о чем вы думаете.
У вас пересохло в горле от волнения и хотите пить. Да, пойдите, уталите жажду.
Другая вещь, о которой вы, вероятно, думаете, такова: что хорошего в том, что она может вставлять какой-то DOM в пустое окно, если оно не стилизовано? Может быть, если это может себе позволить Wikipedia, никто и не заметит, но ваш сайт лучший, вы не можете позволить открыть окно чата без стилей.
Ну, хорошие новости, все возможно!
Сначала я надеялся, что будет простой способ скопировать стили в новое окно. Затем я вспомнил, что моя жизнь — это не что иное, как серия бессмысленных заданий, чтобы заполнить минуты и часы, их единственная цель — отвлечь меня от глубокой, воющей пустоты внутри.
Так что написать функцию было весело!
Вот она:
Весь этот styleSheet
выглядит не очень красиво, поэтому я с нетерпением жду, когда со мной поделятся умным способом сделать это.
Теперь я могу скопировать стили сразу после открытия нового окна:
Вот готовый пример на codepen:
Я не думаю, что это будет работать из приложения Medium на iOS / Android, поэтому нажмите значок codepen в правом верхнем углу, чтобы открыть его в браузере.
Я думаю, что это конец поста.
Всем пока!