Иногда ваше приложение растет, и многие функции перемещаются во всплывающие окна. Что, если приложение использует более 100 модальных окон? Как всем управлять? Как повторно использовать?

Этот туториал покажет вам, как создать очень полезный и мощный контроллер всплывающих окон для управления всеми вашими всплывающими окнами и вызова их из любого места с любым реквизитом, который вам нужен.

Мы будем использовать React Hooks и React Context для создания простого провайдера для управления всем, что нам нужно.

  1. Создание базового React Context based on Hook :

2. Добавление основных модальных состояний:

modals : Все указанные модальные окна.

modal : Состояние выбранных модальных окон для рендеринга.

Как это работает: у нас есть набор указанных модальных окон. Затем все выбранные модальные окна будут отображаться внутри провайдера поверх нашего приложения.

3. Реализация всех необходимых методов для управления нашими состояниями:

openModal: позволяет нам открывать любое модальное окно, передавая modal key в качестве аргумента

closeModal : закрыть модальные окна. Если мы передадим modal key в качестве аргумента — этот метод закроет только определенное модальное окно. Если аргументы не будут переданы — закроются все открытые модальные окна

addModal: разрешить динамическое добавление любых модальных окон

4. Завершенная реализация:

Как это использовать?

Мы создали наш основной провайдер для модальных окон, давайте использовать его

  1. Создайте простое модальное окно (например, мы будем использовать Material-UI)
//TestModal.tsx (Example with @material-ui Dialog)
import { Dialog } from '@material-ui/core';
import { useModals } from '../modals-provider.tsx';
...
const TestModal = (props) => {
    const { closeModal } = useModals();
    const { anyProp } = props;
    return (
        <Dialog onClose={() => closeModal('TEST_MODAL')} open>
            Some modal content
            { anyProp }
        </Dialog>
    );
}
export default TestModal;
  1. Создание Modals object :
//modals file modals/index.tsx;
import TestModal from './TestModal';
export default {
    TEST_MODAL: TestModal,
}

2. Оберните наше приложение ModalsProvider :

// Main app file like App.tsx
import { ModalsProvider } from './modals-provider.tsx';
import modals from './modals';
...
    <ModalsProvider initialModals={modals}>
        <Layout>
            <Switch>
                <Route path="/some-page" exact>
                    <Page />
                </Route>
                ...
            </Switch>
        </Layout>
    </ModalsProvider>

3. И просто используйте его в любом месте вашего приложения:

//Page.jsx
import { useModals } from './modals-provider.tsx';
...

const Page = () => {
  const { openModal } = useModals();
  return (
      <div>
          <Button 
              onClick={() => openModal(
                  'TEST_MODAL', 
                  { anyProp: 'value' }
              )}>
            Sign In
          </Button>
      </div>
  );
};

Это все. Я использовал этот подход и создал небольшой npm-пакет. Проверь это: