React로 Modal 만들기
14432 단어 react-modalReactreact-hooks
React를 사용하여 Modal을 작성했다는 이야기
결론
이번에는 도서관을 사용한다고 말하는 것에 침착했다.
거기에 이르기까지의 경위
1.hooks & Portal 사용
포털이란?
포털은 부모 구성 요소의 DOM 계층 구조 외부의 DOM 노드에 대한 하위 구성 요소를 렌더링하는 공식 메커니즘을 제공합니다. (인용: htps : // 그럼. Rea ctjs. rg / cs / rta ls. HTML )
구현 방법
index.html에 model용 DOM 설치
index.html<!doctype html>
<html lang="ja">
<head>
<title>modal test</title>
<meta charset="UTF-8">
<meta name="format-detection" content="telephone=no">
<meta name="keywords" content="~~"><meta name="description" content="~~">
<meta name="viewport" content="width=device-width">
<link rel="icon" href="/favicon.png">
</head>
<body>
<main role="main">
<div id="app"></div>
<div id="modal"></div>
</main>
<script src="/js/main.js"></script>
</body>
</html>
id="modal"
아래에 렌더링 할 구성 요소 만들기
ModalPortal.jsximport ReactDOM from 'react-dom';
export const ModalPortal = ({ children }) => {
// index.html内にあるid=modalの要素を取得
const el = document.getElementById('modal');
// children = modal を el = modal要素 へ レンダー
return ReactDOM.createPortal(children, el);
};
이것으로 모드를 표시할 준비가 완료된 후에는 모드의 내용의 컴퍼넌트를 준비
다음 구성 요소는 ModalPortal
의 children
값입니다.
Modal.jsxexport const Modal = () => {
return (
<div>
<h3>Modalコンポーネント</h3>
<button>閉じる</button>
</div>
);
};
그리고
App.jsximport ReactDOM from 'react-dom';
import Modal from "./Modal";
import ModalPortal from "./ModalPortal";
import 'react-hot-loader'
const app = document.getElementById('app')
const App = () => {
return (
<div>
<h1>Modal実装したった</h1>
<ModalPortal>
<Modal />
</ModalPortal>
</div>
)
}
ReactDOM.render(<App />,app)
그런 다음 useState, useRef에서 처리를 추가하여 Modal 같은 동작을 구현합니다.
useRef와 useState의 처리에 대해 가볍게 설명
useState에서 버튼을 눌렀을 때에, 모달을 표시할지의 state를 준비해, 표시 비표시를 실시하고 있습니다.
useRef에서는, modal의 외측을 클릭했을 때, 숨기기를 실시하기 위해서 클릭된 요소가 외측의 요소인지 판정시키기 위해서 준비하고 있습니다. (손 빼고 미안합니다.)
왜 그만두었는가
modal내에서 model외로의 onClick에서도 발화해 버린다.
방금 전에 useRef에서 바깥쪽을 클릭했을 경우 모달을 숨기게 한다는 것이었습니다만, 안쪽에서 바깥쪽으로의 클릭으로도 발화해 버린다.
생각할 수 있는 대책 방법
onClick 대신 mousedown과 touchstart로 요소를 구분합니다. mousedown과 touchstart 두 가지 필요한 이유는 PC와 SP에서 이벤트 발화가 다르기 때문에 두 가지 준비해야합니다.
하지만, 스크롤 때도 발화하지 않을까 등 불안 요소가 있었기 때문에, 시간이 걸리려고 느끼고 단념했습니다
2.react-modal 사용
구현 시간도 제한되어 있으므로 라이브러리에서 해 봅시다.
구현 내용
이미지대로 install에서 가서
// npm
$ npm install --save react-modal
// yarn
$ yarn add react-modal
import React, { useState } from 'react'
import { jsx } from '@emotion/react'
import Modal from 'react-modal'
export const useModal = () => {
const [modal, setModal] = useState(false)
const modalOpen = () => { setModal(true) return }
const modalClose = () => { setModal(false) }
return { modal, modalOpen, modalClose }
}
export const ModalBox = (props) => {
Modal.setAppElement('#modal')
const customStyles = {
overlay: { position: 'fixed', top: 0, width: '100%', height: '100%'},
content: { position: 'static', maxWidth: props.maxWidth}
};
const modalClose = () => { props.close() }
return (
<Modal isOpen={props.modal} onRequestClose={modalClose} style={customStyles}>
{props.children}
</Modal>
);
};
<!doctype html>
<html lang="ja">
<head>
<title>modal test</title>
<meta charset="UTF-8">
<meta name="format-detection" content="telephone=no">
<meta name="keywords" content="~~"><meta name="description" content="~~">
<meta name="viewport" content="width=device-width">
<link rel="icon" href="/favicon.png">
</head>
<body>
<main role="main">
<div id="app"></div>
<div id="modal"></div>
</main>
<script src="/js/main.js"></script>
</body>
</html>
import ReactDOM from 'react-dom';
export const ModalPortal = ({ children }) => {
// index.html内にあるid=modalの要素を取得
const el = document.getElementById('modal');
// children = modal を el = modal要素 へ レンダー
return ReactDOM.createPortal(children, el);
};
export const Modal = () => {
return (
<div>
<h3>Modalコンポーネント</h3>
<button>閉じる</button>
</div>
);
};
import ReactDOM from 'react-dom';
import Modal from "./Modal";
import ModalPortal from "./ModalPortal";
import 'react-hot-loader'
const app = document.getElementById('app')
const App = () => {
return (
<div>
<h1>Modal実装したった</h1>
<ModalPortal>
<Modal />
</ModalPortal>
</div>
)
}
ReactDOM.render(<App />,app)
// npm
$ npm install --save react-modal
// yarn
$ yarn add react-modal
import React, { useState } from 'react'
import { jsx } from '@emotion/react'
import Modal from 'react-modal'
export const useModal = () => {
const [modal, setModal] = useState(false)
const modalOpen = () => { setModal(true) return }
const modalClose = () => { setModal(false) }
return { modal, modalOpen, modalClose }
}
export const ModalBox = (props) => {
Modal.setAppElement('#modal')
const customStyles = {
overlay: { position: 'fixed', top: 0, width: '100%', height: '100%'},
content: { position: 'static', maxWidth: props.maxWidth}
};
const modalClose = () => { props.close() }
return (
<Modal isOpen={props.modal} onRequestClose={modalClose} style={customStyles}>
{props.children}
</Modal>
);
};
여담
Modal을 작성한 후 찾은 편리한 후크를 소개하고 싶습니다.
방금 외부의 onClick 문제를 해결한 것입니다.
Reference
이 문제에 관하여(React로 Modal 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/nakamo-03/items/3f57b861742871ceacc8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)