Как создать модальное окно в React JS

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

Как и многие другие компоненты в React, можно установить зависимость, которая поможет в этом процессе, однако в итоге мы всегда оказываемся ограничены в нескольких аспектах, и один из них — это стилизация.

По этой причине у меня возникла идея создать эту статью, в которой мы будем использовать уже известные нам знания из области css, props и hooks.

Установим библиотеку иконок

	
npm install react-icons

Теперь мы можем сразу же приступить к работе над нашим Modal.jsx. Но сначала давайте поговорим о CSS.

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

Затем наш компонент будет разделен на три области, первая — заголовок, где можно разместить заголовок модала. Вторая часть — содержимое, здесь можно поместить нужное сообщение.

Третья и последняя часть — это действия, которые могут быть выполнены в модале, то есть отмена модала для его закрытия и другие действия (сохранение, обновление, удаление и т.д.).

Теперь, когда у нас есть несколько понятий, вы можете скопировать этот же css (вы можете свободно играть с ним для настройки вашего модала):

	
/* @src/components/Modal.module.css */

.darkBG {
  background-color: rgba(0, 0, 0, 0.2);
  width: 100vw;
  height: 100vh;
  z-index: 0;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  position: absolute;
}

.centered {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.modal {
  width: 250px;
  height: 170px;
  background: white;
  color: white;
  z-index: 10;
  border-radius: 16px;
  box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.04);
}

.modalHeader {
  height: 50px;
  background: white;
  overflow: hidden;
  border-top-left-radius: 16px;
  border-top-right-radius: 16px;
}

.heading {
  margin: 0;
  padding: 10px;
  color: #2c3e50;
  font-weight: 500;
  font-size: 18px;
  text-align: center;
}

.modalContent {
  padding: 10px;
  font-size: 14px;
  color: #2c3e50;
  text-align: center;
}

.modalActions {
  position: absolute;
  bottom: 2px;
  margin-bottom: 10px;
  width: 100%;
}

.actionsContainer {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.closeBtn {
  cursor: pointer;
  font-weight: 500;
  padding: 4px 8px;
  border-radius: 8px;
  border: none;
  font-size: 18px;
  color: #2c3e50;
  background: white;
  transition: all 0.25s ease;
  box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.06);
  position: absolute;
  right: 0;
  top: 0;
  align-self: flex-end;
  margin-top: -7px;
  margin-right: -7px;
}

.closeBtn:hover {
  box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.04);
  transform: translate(-4px, 4px);
}

.deleteBtn {
  margin-top: 10px;
  cursor: pointer;
  font-weight: 500;
  padding: 11px 28px;
  border-radius: 12px;
  font-size: 0.8rem;
  border: none;
  color: #fff;
  background: #ff3e4e;
  transition: all 0.25s ease;
}

.deleteBtn:hover {
  box-shadow: 0 10px 20px -10px rgba(255, 62, 78, 0.6);
  transform: translateY(-5px);
  background: #ff3e4e;
}

.cancelBtn {
  margin-top: 10px;
  cursor: pointer;
  font-weight: 500;
  padding: 11px 28px;
  border-radius: 12px;
  font-size: 0.8rem;
  border: none;
  color: #2c3e50;
  background: #fcfcfc;
  transition: all 0.25s ease;
}

.cancelBtn:hover {
  box-shadow: none;
  transform: none;
  background: whitesmoke;
}

Как видите, все css-классы очень просты, теперь мы можем приступить к работе над нашим Modal.jsx.

	
// @src/components/Modal.jsx

import React from "react";

const Modal = () => {
  return 

Hello Modal

; }; export default Modal;

Одним из первых элементов, которые мы собираемся добавить, являются стили, и в этой статье мы будем использовать модули css.

	
// @src/components/Modal.jsx

import React from "react";
import styles from "./Modal.module.css";

const Modal = () => {
  return 

Hello Modal

; }; export default Modal;

В нашем модале должна быть кнопка закрытия, и для этого нам понадобится иконка, таким образом мы импортируем иконку, которая будет использоваться:

	
// @src/components/Modal.jsx

import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";

const Modal = () => {
  return 

Hello Modal

; }; export default Modal;

Хочу обратить ваше внимание на то, что нам нужно будет получать props, чтобы мы могли закрыть модальное окно, как только оно будет открыто. Поэтому мы получим один props, который будет представлять собой функцию setIsOpen().
После всего этого мы можем приступить к работе над нашим шаблоном. Сначала мы добавим темный фон, чтобы придать модалу больше акцента при его открытии.

Как только пользователь щелкнет на темном фоне, мы захотим закрыть модальное окно, поэтому добавим событие реакции onClick и передадим в качестве единственного аргумента функции setIsOpen() число boolean (в данном случае оно будет равно false).

	
// @src/components/Modal.jsx

import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";

const Modal = ({ setIsOpen }) => {
  return (
    <>
      
setIsOpen(false)} /> // ... ); }; export default Modal;

Теперь мы займемся нашим модалом, для чего добавим обертку для центрирования модала на экране (.centered), а также тело модала (.modal) и его заголовок (.modalHeader).

Мы можем добавить кнопку, содержащую пиктограмму закрытия модала, которая будет содержать событие onClick, а также передавать функции setIsOpen() значение false, чтобы мы могли закрыть модал, как только эта кнопка будет нажата.

Добавим содержимое нашего модала (.modalContent).

	
// @src/components/Modal.jsx

import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";

const Modal = ({ setIsOpen }) => {
  return (
    <>
      
setIsOpen(false)} />
Dialog
Are you sure you want to delete the item?
// ...
); }; export default Modal;

Добавим стили к кнопкам

	
// @src/components/Modal.jsx

import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";

const Modal = ({ setIsOpen }) => {
  return (
    <>
      
setIsOpen(false)} />
Dialog
Are you sure you want to delete the item?
); }; export default Modal;

Теперь, когда наш модальный компонент готов, просто добавьте его в наш App.jsx, но сначала давайте создадим следующие стили, чтобы иметь более удобную кнопку на нашей странице:

	
/* @src/App.module.css */

.primaryBtn {
  margin: 20px 10px;
  cursor: pointer;
  font-weight: 500;
  padding: 13px 25px;
  border-radius: 15px;
  font-size: 0.8rem;
  border: none;
  color: white;
  background: #185adb;
  transition: all 0.25s ease;
}

.primaryBtn:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 20px -10px rgba(24, 90, 219, 0.6);
}

Теперь мы можем приступить к работе над нашим App.jsx. Сначала мы импортируем useState() и создадим состояние isOpen и функцию setIsOpen.
Затем мы просто сделаем условный рендеринг, чтобы показывать модальное окно только тогда, когда состояние isOpen равно true. Аналогичным образом мы передадим функцию setIsOpen() в качестве props.

	
// @src/App.jsx

import React, { useState } from "react";
import styles from "./App.module.css";

import Modal from "./components/Modal";

const App = () => {
  const [isOpen, setIsOpen] = useState(false);
  return (
    
{isOpen && }
); }; export default App;

Вы должны получить результат, аналогичный этому:

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии