Модальні вікна в React — складна тема
Найкращі практики архітектурних рішень в React значно ускладнюють процес створення модальних вікон.
Щоб створити хороший модальний компонент в React, нам слід:
- Додати його в кінець
body
(з причин доступності). Це не властиво React, де компоненти розташовуються на початку батьківського компонента. - Закріпити модальні компоненти в DOM, лише коли вони показані.
- Видалити модальні компоненти з DOM, коли вони приховані.
- Не впливати на DOM безпосередньо, використовуючи такі бібліотеки, як jQuery.
Що ми створимо
У статті ми з'ясуємо, як створити компонент модального вікна в React, котрий з'являється та приховується одним кліком. Наприкінці отримаємо щось подібне:
Створення користувацького модального хука
Почнемо зі створення користувацького хука React для запуску нашого модального компонента. Якщо ви досі не мали справу з React Hooks, перегляньте цей вступ.
Хук у React — функція, яка розділяє загальну логіку між декількома компонентами. Наприклад, показування та приховування модального компонента.
Почнемо зі створення нового файлу useModal.js
. Завжди додавайте до назви хуку use
на початку.
import { useState } from 'react';
const useModal = () => {
const [isShowing, setIsShowing] = useState(false);
function toggle() {
setIsShowing(!isShowing);
}
return {
isShowing,
toggle,
}
};
export default useModal;
Ось що відбувається у наведеному фрагменті:
- Встановлюємо нові значення для стану
isShowing
іsetIsShowing
, щоб зберегти поточний вигляд модального вікна. - Оголошуємо функцію
toggle
, яка змінює значенняisShowing
на протилежне. - Повертаємо значення
isShowing
та функціюtoggle
з хука, щоб компонент мав до них доступ.
Створення модального компонента React
Тепер у нас є готовий користувацький хук, тому ми можемо створити модальний компонент, щоб безпосередньо рендерити його.
import React from 'react';
import ReactDOM from 'react-dom';
const Modal = ({ isShowing, hide }) => isShowing ? ReactDOM.createPortal(
<React.Fragment>
<div className="modal-overlay"/>
<div className="modal-wrapper" aria-modal aria-hidden tabIndex={-1} role="dialog">
<div className="modal">
<div className="modal-header">
<button type="button" className="modal-close-button" data-dismiss="modal" aria-label="Close" onClick={hide}>
<span aria-hidden="true">×</span>
</button>
</div>
<p>
Hello, I'm a modal.
</p>
</div>
</div>
</React.Fragment>, document.body
) : null;
export default Modal;
Найімовірніше, цей фрагмент коду не потребує пояснень. Модальне вікно — функціональний stateless-компонент, який приймає два prop і повертає HTML, якщо значення isShowing
—true
.
Однак погляньте на код, який огортає дочірні елементи модального компонента (особливо зверніть увагу на кінець першого рядка).
const Modal = ({ isShowing, hide }) => isShowing ? ReactDOM.createPortal(
<React.Fragment>
...
</React.Fragment>, document.body
) : null;
Що таке Portal
?
Портал в інший вимір DOM
Портали дозволяють компонентам React рендеритись в іншій частині DOM, що розташований поза їхнім батьківським компонентом.
Тому ми можемо використати портал для монтування нашого модального компонента у кінець елемента document.body
, а не використовувати його як дочірній елемент іншого компонента.
У наведеному вище фрагменті з такою метою ми визначили два аргументи для функції createPortal
: модальний компонент, який ми хочемо рендерити, та місце, куди його необхідно приєднати.
Використання модальних компонентів у React
Зрештою об'єднаймо користувацький хук та модальний компонент:
import React from 'react';
import './App.css';
import Modal from "./Modal";
import useModal from './useModal';
const App = () => {
const {isShowing, toggle} = useModal();
return (
<div className="App">
<button className="button-default" onClick={toggle}>Show Modal</button>
<Modal
isShowing={isShowing}
hide={toggle}
/>
</div>
);
};
export default App;
Всередині компонента ми імпортуємо користувацький React Hook та ініціалізуємо isShowing
та toggle
.
const {isShowing, toggle} = useModal();
Далі ми вказуємо toggle
як обробник onClick
, котрий встановлює значення isShowing
як true
при натисканні на кнопку.
<button className="button-default" onClick={toggle}>Show Modal</button>
Наприкінці ми передаємо isShowing
та toggle
через props модального компонента, щоб мати до них доступ.
Результат:
Як ми і казали, це найпростіше рішення для створення модальних вікон в React: з отриманим користувацьким хуком ви можете використовувати однакову логіку для різноманітних типів і стилів модальних вікон.
Ще немає коментарів