Команда Whitespectre создала библиотеку rn-modal-presenter для решения проблем с множественными модальными окнами в React Native.
❌ Проблемы стандартного подхода
1. Управление состояниями — нужна переменная для каждого модального окна
2. iOS ограничение — нельзя показать >1 модального окна одновременно
3. Размонтирование — при навигации модалки исчезают
4. Тихие ошибки — вторая модалка не появляется без предупреждений
Пример проблемы:
const App = () => {
const [showRateAppModal, setShowRateAppModal] = useState(false);
const [showAppRatedPositiveModal, setShowAppRatedPositiveModal] = useState(false);
const [showAppRatedNegativeModal, setShowAppRatedNegativeModal] = useState(false);
const [showActivateGadgetModal, setShowActivateGadgetModal] = useState(false);
return (
<SafeAreaView>
{showActivateGadgetModal && <ActivateGadgetModal />}
{showRateAppModal && <RateAppModal />}
{showAppRatedPositiveModal && <PositiveFeedbackModal />}
{showAppRatedNegativeModal && <NegativeFeedbackModal />}
</SafeAreaView>
);
};Проблемы:
🔸 4 переменные состояния для 4 модалок
🔸 Сложная логика управления
🔸 При одновременном показе двух модалок — молчаливая ошибка на iOS
Почему сторонние библиотеки не помогли
react-native-modal:
🔸 Расширяет стандартный Modal
🔸 Те же ограничения iOS
🔸 Не решает проблему множественных окон
react-native-modalfy:
🔸 Поддерживает множественные модалки (JS-реализация)
❌ Много boilerplate кода
❌ Нельзя показать несколько экземпляров одной модалки
✅ Решение: rn-modal-presenter
Преимущества:
1. Императивный API — вызов из любого места
2. Без состояний — не нужны useState
3. Множественные модалки — из коробки
4. Гибкость — любой компонент как модалка
5. 100% JavaScript — работает кроссплатформенно
Установка:
yarn add @whitespectre/rn-modal-presenter
Использование:
import { ModalPresenterParent, showModal } from '@whitespectre/rn-modal-presenter';
const App = () => (
<ModalPresenterParent>
<SafeAreaView>
<Button
title="Activate Gadget"
onPress={() => showModal(ActivateGadgetModal, {})}
/>
</SafeAreaView>
</ModalPresenterParent>
);Модалка управляет собой:
const ActivateGadgetModal = ({dismiss}: ModalContentProps) => (
<View style={styles.modal}>
<Text>Your Gadget has been activated</Text>
<Button
title="Close"
onPress={() => {
dismiss();
showModal(RateAppModal, {});
}}
/>
</View>
);Сравнение подходов
Standard Modal:
❌ Много состояний
❌ Нет множественных модалок
❌ iOS ограничения
❌ Нет императивного API
react-native-modal:
❌ Много состояний
❌ Нет множественных модалок
❌ iOS ограничения
❌ Нет императивного API
react-native-modalfy:
✅ Без состояний
✅ Множественные модалки
✅ Императивный API
🔸Много boilerplate
rn-modal-presenter:
✅ Без состояний
✅ Множественные модалки
✅ Императивный API
✅ Минимум кода
✅ Несколько экземпляров одной модалки
Планы развития
🔸 Очередь модальных окон
🔸 Система приоритетов
🔸 Показ поверх Native вьюх
🔸 Кастомная анимация
Итог⬇️
rn-modal-presenter упрощает работу с множественными модальными окнами, убирая управление состояниями и предоставляя императивный API. Идеально для сложных флоу с несколькими последовательными модалками.
📎 Статья
🎙 Новости
📝 База вопросов
