Немного вводных:
- Любая модалка может быть показана на любой странице
- Любая модалка может быть вызвана любым компонентом
Я посчитал что вставлять модалки на каждую страницу и добавлять состояние для её показа - это говно.
И я не уверен что пришёл к лучшему решению, но уверен что это намного лучше, чем описанное выше.
Погуглив, решил обернуть весь роутер в провайдер, в котором все модальные окна и показывать нужный через прослушивание глобального состояния.
В качестве менеджера выбрал атомарный "Джотай":
export const ModalProvider = (props?: IProps) => {
const [modal, setModal] = useAtom(derivedModalAtom);
const {type, isShown} = modal;
const isInterlocutorFoundShown = type === 'InterlocutorFound' && isShown;
const isSearchChatShown = type === 'SearchChat' && isShown;
const isQuitChatShown = type === 'QuitChat' && isShown;
const isEndChatShown = type === 'EndChat' && isShown;
return (
<ModalContext.Provider value={modal}>
{props?.children}
{isInterlocutorFoundShown && (<InterlocutorFoundModal/>)}
{isSearchChatShown && (<SearchChatModal/>)}
{isQuitChatShown && (<QuitChatModal/>)}
{isEndChatShown && (<EndChatModal/>)}
</ModalContext.Provider>
);
};
Вызов:
const SomeComponent = (props: IProps) => {
const [modal, setModal] = useAtom(derivedModalAtom);
const onPress = () => setModal({
type: 'InterlocutorFound',
isShown: true,
});
return <Button onPress={onPress}></Button>
}