Comments 17
Аксиома: любой проект рано или поздно в своем ui-ките приходит к порталам для всплывашек. Лучше рано.
Почитать теорию можно тут
Почему бы не вызывать их отдельной общей функцией, например так:
onClick={ ()=>{ openPopup(MyPopup); } }
чтобы они рендерирились в отдельном общем компоненте поближе к корню документа, как в вашем случае с порталами? Или даже в отдельном дереве react компонентов, а не в общем. Не появились бы порталы в react, вам бы скорее всего пришлось использовать подобное решение.
Контекстные попапы это хорошо, но идея в другом (если я правильно понял): вместо того, чтобы специально рендерить вручную диалог подтверждения, или какой иной, можно воспользоваться некоторой функцией openPopup, которая рендерит попап и, допустим, возвращает промис с ответом юзера. Тогда с async/await мы получаем те же удобства, как если бы использовали встроенную браузерную функцию confirm. Ну то есть в какой-то функции захотели спросить, и прямо спрашиваем.
Разумеется, рендерить в отдельное дерево компонентов — так себе идея: в попапе не будет доступа к контекстам, да и вообще бедпрактис, а можно сделать в корне проекта специальную "попапилку", к которой потом подключаться через контекст: const openPopup = usePopuper(MyPopup), как-то так.
Тема близка мне, ибо делаю такое прямо сейчас )
Вторая проблема почему я отказался, это то что если все попапы хранить в одном месте их там собирается иногда больше 50. И ты уже не особо ориентируешь, какие еще используются, какие легаси и управлять этим становится сложнее
Третья проблема, это например ты создаешь пользователя в попапе, и один из пунктов это загрузить аватарку, по требованиям при загрузке фото нужно скрыть прошлый попап и показать попап с кропом картинки, а после кропа вернуть в прежний попап с прежними данными. В итоге из-за того что оба эти попапа контекстные, у меня нет проблем с хранением состояние между переключающимися попапами
Таких примеров с неудоствами можно много перечислять, это лишь первые которые я вспомнил из своего опыта. Каждый попап требует индивидуального подхода, по крайней мере мне такая идеология нравится
Ты открыл попап и пока заполняешь форму, промис висит все это время.
Ну и пусть висит. Потом всё равно зарезолвится, по закрытии попапа.
Вторая проблема почему я отказался, это то что если все попапы хранить в одном месте их там собирается иногда больше 50.
const openPopup = usePopuper(MyPopup) — вот тут используется свой, локальный попап, не из общей копилки. Просто он будет отрендерен неким общим элементом по запросу.
создаешь пользователя в попапе, и один из пунктов это загрузить аватарку, по требованиям при загрузке фото нужно скрыть прошлый попап и показать попап с кропом картинки, а после кропа вернуть в прежний попап с прежними данными.
Нижний попап можно просто делать на время невидимым.
Вообще, я не утверждаю, что абсолютно все диалоги надо всплывать именно таким способом. Но если понадобилось о чем-то спросить пользователя в середине функции, то заэвайтить попапчик намного удобнее, чем разрезать функцию, рендерить попап (для чего менять какой-нибудь стейт isConfirmVisible) и у него в кнопке ОК в онклике делать остаток функции.
Вторая проблема почему я отказался, это то что если все попапы хранить в одном месте их там собирается иногда больше 50.Удалять их при закрытии. У себя ведь удаляете:
document.body.removeChild(container);
Вряд-ли будет проект с необходимостью держать открытыми 50 попапов одновременно)В целом понятны ваши мотивы. Спасибо!
Интересно, что раньше порталов и контекстов не было, но в большинстве плагинов использовался подход с написанием popup-ов в jsx коде компонента-родителя и проблему с z-index там нельзя было решить как сейчас.
1. хранить в виде flat list в одном месте — тут мы уже все сошлись, что это неудобно
2. хранить в одном месте но поделить их по доменам, чуть лучше, но все равно проблема остается, что у тебя будут в некоторых доменах богом забытые попапы
3. хранить не в одном месте, а рядом с тем кодом где попап и вызывается — в таком случае у менеджера попапов будут импорты по всему проекту, да еще и глубокие импорты, это все надо поддерживать на дистанции, ну такое как по мне
хранить не в одном месте, а рядом с тем кодом где попап и вызывается — в таком случае у менеджера попапов будут импорты по всему проекту, да еще и глубокие импортыБудет импорт менеджера туда, где он используется, местами испорт попапов из одной страницы в другую. При желании можно в корне проекта в файл импортировать все попапы, а оттуда экспортировать их; или регистрировать их в менеджере; IoС контейнер, контекст использовать. В общем, доступен полный набор решений, который используется для остальных файлов в проекте. Какое-то персональное решение только для попапов и ни для чего больше изобретать не нужно.
Как мы решили проблемы с z-index