Pull to refresh

Comments 17

Очень интересное решение и красивое решение.
Да, мне тоже оно настолько понравилось, что решил опубликовать, мало ли кому еще пригодится)
Оно вроде как 100 летнее и очевидное, но если кто не знал, то теперь вы знаете)
мы только недавно к нему пришли) поэтому и решили поделиться, мало ли у кого такие же проблемы

Аксиома: любой проект рано или поздно в своем ui-ките приходит к порталам для всплывашек. Лучше рано.
Почитать теорию можно тут

Мне другое не понятно, откуда и зачем пошла мода писать jsx код popup-компонентов в том же компоненте, в котором этот popup вызывается?
Почему бы не вызывать их отдельной общей функцией, например так:
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 там нельзя было решить как сейчас.
про 50 попапов я имел ввиду, в папке где ты хранишь попапы, у тебя там много файлов выходит, а не про то что я из DOM не удаляю
Это уже проблема с организацией файлов в проекте и к попапам отношения не имеет. Ничто не мешает располагать их по фичам/доменам, рядом с основной страницей, где они используются.
это относится к попапам, хоть и косвенно. Если ты работаешь с попапами через единый менеджер попапов, тогда ты обретаешь проблему где хранить эти попапы и хороших вариантов как хранить 50 попапов я не вижу, какие есть варианты:
1. хранить в виде flat list в одном месте — тут мы уже все сошлись, что это неудобно
2. хранить в одном месте но поделить их по доменам, чуть лучше, но все равно проблема остается, что у тебя будут в некоторых доменах богом забытые попапы
3. хранить не в одном месте, а рядом с тем кодом где попап и вызывается — в таком случае у менеджера попапов будут импорты по всему проекту, да еще и глубокие импорты, это все надо поддерживать на дистанции, ну такое как по мне
То же самое относится к страницам и ко многим компонентам. Если вы решили проблему с богом забытыми файлами в проекте, то и проблема с попами решается точно так же.
хранить не в одном месте, а рядом с тем кодом где попап и вызывается — в таком случае у менеджера попапов будут импорты по всему проекту, да еще и глубокие импорты
Будет импорт менеджера туда, где он используется, местами испорт попапов из одной страницы в другую. При желании можно в корне проекта в файл импортировать все попапы, а оттуда экспортировать их; или регистрировать их в менеджере; IoС контейнер, контекст использовать. В общем, доступен полный набор решений, который используется для остальных файлов в проекте. Какое-то персональное решение только для попапов и ни для чего больше изобретать не нужно.
Тоже использую, удобно, когда во время выполнения чего — либо надо показать юзеру модалку и дальше продолжать исполнение в зависимости от ответа, такой вот кастомный confirm, как вы и сказали.
Sign up to leave a comment.

Articles