【React】Portal+Context+Hooks 로 모달 다이얼로그를 간단하게 취급
포털이란?
ReactDOM.createPortal() 는 컴퍼넌트 계층의 외부(=#root 와 같은 계층)의 DOM 요소에 컴퍼넌트를 렌더링 하는 메소드입니다.
이것에 의해 컴퍼넌트 계층에서의 z-index 를 신경쓰지 않고 모달 다이얼로그를 표시하는 것이 가능하게 됩니다.
개폐의 제어가 버킷 릴레이가 되는 것을 피하기 위해서, 기술을 간결하게 하기 위해서 Context 와 Hooks 를 이용해 가능한 한 간단하게 취급할 수 있는 모달 다이얼로그를 구현해 봅니다.
(알기 쉬운 모양을 위해 SemanticUI 를 사용하고 있으므로 실제로 실행하는 경우는 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css"/> 를 추가해 주세요)
구현
루트 노드
모달에 대한 루트 노드를 추가합니다.
index.html<!-- 省略 -->
<div id="modal"></div>
<!-- 省略 -->
Context
useState() 에서 사용할 수 있는 형태로 Context 를 정의합니다.
isModalShown.jsimport React from 'react';
export default React.createContext({
isModalShown: false, // モーダル開閉ステータス
toggleModalShown: () => {}, // ステータス更新関数
});
모달 다이얼로그 본체
Hooks를 사용하지 않는 경우와 비교하면 상당히 깔끔하게 쓸 수 있습니다.
제목과 텍스트는 props로 전달해야하지만 이번에는 생략합니다.
Modal.jsximport React, { useContext } from 'react';
import ReactDOM from 'react-dom';
import isModalShown from '../contexts/isModalShown';
const Modal = () => {
// 背景とCloseボタンのクリックで開閉ステータスをfalseにする
const renderModal = modalHookState => {
const [isModalShown, changeShownModal] = modalHookState;
return (
<div
onClick={() => changeShownModal(false)}
className="ui dimmer modals visible active"
>
<div
onClick={e => e.stopPropagation()}
className="ui standard modal visible active"
>
<div className="ui header">Modal Dialog</div>
<div className="content">This is modal dialog with Context</div>
<div className="actions">
<button
className="ui button primary"
onClick={() => changeShownModal(false)}
>
Close
</button>
</div>
</div>
</div>
);
};
// Contextの値を取得して開閉制御
const modalHookState = useContext(isModalShown);
return ReactDOM.createPortal(
modalHookState[0] && renderModal(modalHookState),
document.querySelector('#modal'),
);
};
export default Modal;
모달을 부르는 측면의 구성 요소
모달 개폐 상태를 업데이트하는 함수를 onClick에 바인딩합니다.
CallModal.jsximport React, { useContext } from 'react';
import isModalShown from '../contexts/isModalShown';
import Modal from './Modal';
const CallModal = () => {
// Open Modalボタンクリックで開閉ステータスをtrueにする
const renderCallModal = changeShownModal => {
return (
<div>
<button onClick={() => changeShownModal(true)}>Open Modal</button>
</div>
);
};
return (
<div>
{renderCallModal(useContext(isModalShown)[1])}
<Modal />
</div>
);
};
export default CallModal;
Provider
모달 개폐 상태와 Provider에서 변경할 함수를 전달합니다.
App.jsximport React from 'react';
import isModalShown from '../contexts/isModalShown';
import CallModal from './CallModal';
const App = () => {
// modalState...[isModalShown, toggleModalShown]
const modalState = React.useState(false);
return (
<isModalShown.Provider value={modalState}>
<CallModal />
</isModalShown.Provider>
);
};
export default App;
결과

버킷 릴레이를 피함으로써, Modal까지의 컴포넌트가 깊게 중첩했을 때의 재이용성이나 독립성을 높일 수 있었습니다.
표시/숨기기를 전환할 때는 반드시 Context의 값을 변경하면 되므로 취급하기 쉽다고 생각합니다.
참고 URL
htps : // Rea ctjs. rg / cs / 이렇게 xt. HTML
htps : // Rea ctjs. 오 rg / 드 cs / 호오 ks - 레페 렌세. HTML
Reference
이 문제에 관하여(【React】Portal+Context+Hooks 로 모달 다이얼로그를 간단하게 취급), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuuyun/items/7edc544361df3ec3455d
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
루트 노드
모달에 대한 루트 노드를 추가합니다.
index.html
<!-- 省略 -->
<div id="modal"></div>
<!-- 省略 -->
Context
useState() 에서 사용할 수 있는 형태로 Context 를 정의합니다.isModalShown.js
import React from 'react';
export default React.createContext({
isModalShown: false, // モーダル開閉ステータス
toggleModalShown: () => {}, // ステータス更新関数
});
모달 다이얼로그 본체
Hooks를 사용하지 않는 경우와 비교하면 상당히 깔끔하게 쓸 수 있습니다.
제목과 텍스트는 props로 전달해야하지만 이번에는 생략합니다.
Modal.jsx
import React, { useContext } from 'react';
import ReactDOM from 'react-dom';
import isModalShown from '../contexts/isModalShown';
const Modal = () => {
// 背景とCloseボタンのクリックで開閉ステータスをfalseにする
const renderModal = modalHookState => {
const [isModalShown, changeShownModal] = modalHookState;
return (
<div
onClick={() => changeShownModal(false)}
className="ui dimmer modals visible active"
>
<div
onClick={e => e.stopPropagation()}
className="ui standard modal visible active"
>
<div className="ui header">Modal Dialog</div>
<div className="content">This is modal dialog with Context</div>
<div className="actions">
<button
className="ui button primary"
onClick={() => changeShownModal(false)}
>
Close
</button>
</div>
</div>
</div>
);
};
// Contextの値を取得して開閉制御
const modalHookState = useContext(isModalShown);
return ReactDOM.createPortal(
modalHookState[0] && renderModal(modalHookState),
document.querySelector('#modal'),
);
};
export default Modal;
모달을 부르는 측면의 구성 요소
모달 개폐 상태를 업데이트하는 함수를 onClick에 바인딩합니다.
CallModal.jsx
import React, { useContext } from 'react';
import isModalShown from '../contexts/isModalShown';
import Modal from './Modal';
const CallModal = () => {
// Open Modalボタンクリックで開閉ステータスをtrueにする
const renderCallModal = changeShownModal => {
return (
<div>
<button onClick={() => changeShownModal(true)}>Open Modal</button>
</div>
);
};
return (
<div>
{renderCallModal(useContext(isModalShown)[1])}
<Modal />
</div>
);
};
export default CallModal;
Provider
모달 개폐 상태와 Provider에서 변경할 함수를 전달합니다.
App.jsx
import React from 'react';
import isModalShown from '../contexts/isModalShown';
import CallModal from './CallModal';
const App = () => {
// modalState...[isModalShown, toggleModalShown]
const modalState = React.useState(false);
return (
<isModalShown.Provider value={modalState}>
<CallModal />
</isModalShown.Provider>
);
};
export default App;
결과

버킷 릴레이를 피함으로써, Modal까지의 컴포넌트가 깊게 중첩했을 때의 재이용성이나 독립성을 높일 수 있었습니다.
표시/숨기기를 전환할 때는 반드시 Context의 값을 변경하면 되므로 취급하기 쉽다고 생각합니다.
참고 URL
htps : // Rea ctjs. rg / cs / 이렇게 xt. HTML
htps : // Rea ctjs. 오 rg / 드 cs / 호오 ks - 레페 렌세. HTML
Reference
이 문제에 관하여(【React】Portal+Context+Hooks 로 모달 다이얼로그를 간단하게 취급), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yuuyun/items/7edc544361df3ec3455d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)