diff --git a/June/article/How-to-handle-multiple-modals-in-a-React-application.md b/June/article/How-to-handle-multiple-modals-in-a-React-application.md
new file mode 100644
index 0000000..abf4912
--- /dev/null
+++ b/June/article/How-to-handle-multiple-modals-in-a-React-application.md
@@ -0,0 +1,278 @@
+## π [How to handle multiple modals in a React application](https://dev.to/zettadam/how-to-handle-multiple-modals-in-a-react-application-2pei)
+
+### ποΈ λ²μ λ μ§: 2024.06.29
+
+### π§ λ²μν ν¬λ£¨: λ¬κΈ°(λ°μ μ°)
+
+---
+
+## 리μ‘νΈ μ΄ν리μΌμ΄μ
μμ μ¬λ¬κ°μ λͺ¨λ¬λ€μ κ΄λ¦¬νλ λ°©λ²
+
+μ°Έκ³ : μ 체 μμ μ ν리μΌμ΄μ
μ μ¬κΈ°μμ νμΈν μ μμ΅λλ€: https://stackblitz.com/edit/react-modals
+
+React μ ν리μΌμ΄μ
μμ λͺ¨λ¬μ κ΄λ¦¬νλ λ°©λ²μ νλλ§ μλ κ²μ΄ μλμ§λ§, λͺλͺ λ°©μμ΄ λ€λ₯Έ λ°©μλ³΄λ€ λμ μ μμ΅λλ€. μ΄ κΈμμλ Redux μ€ν μ΄ κ°μ κΈλ‘λ² μ€ν μ΄λ₯Ό μ¬μ©νμ¬ λͺ¨λ¬μ κ΄λ¦¬νλ κ²λ³΄λ€ λ κ°λ¨ν λ°©λ²μ μκ°νκ³ μ ν©λλ€. μ΄ μμ μμλ μ»΄ν¬λνΈ μνμ μ΄λ²€νΈ λ²λΈλ§μ μ¬μ©ν κ²μ΄λ©°, μ΄λ Reactμ Portalsλ μΈκΈλμ΄ μμ΅λλ€.
+
+λͺ¨λ¬μ λ³΄ν΅ λΌμ°ν°μ μν΄ κ΄λ¦¬λλ λ³λμ νλ©΄κ³Ό λΉμ·ν λΆλΆμ΄ μμ΅λλ€.
+
+## AppShell
+
+μλ₯Ό λ€μ΄ λ€μ src/AppShell.jsx μμ μ κ°μ΄, λ μ’
λ₯μ μ»΄ν¬λνΈλ₯Ό μ€μ μ»΄ν¬λνΈμμ μλ‘ κ°κΉκ² λ λλ§νλ κ²μ΄ ν©λ¦¬μ μΌ μ μμ΅λλ€.
+
+```tsx
+import React, { useState } from 'react'
+import { BrowserRouter, NavLink, Route, Switch } from 'react-router-dom'
+
+import ScreenOne from './components/screen-one/ScreenOne'
+import ScreenTwo from './components/screen-two/ScreenTwo'
+import ScreenThree from './components/screen-three/ScreenThree'
+
+import ModalOne from './components/common/modal-one/ModalOne'
+import ModalTwo from './components/common/modal-two/ModalTwo'
+import ModalThree from './components/common/modal-three/ModalThree'
+
+import './app-shell.css'
+
+const AppShell = () => {
+ const [modalOpen, setModal] = useState(false)
+
+ const openModal = event => {
+ event.preventDefault()
+ const { target: { dataset: { modal }}} = event
+ if (modal) setModal(modal)
+ }
+
+ const closeModal = () => {
+ setModal('')
+ }
+
+ return (
+
+
+
+ {/* Application header and navigation */}
+
+ React Modal Windows
+
+
+
+ {/* Application screens */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Modals */}
+
+
+
+
+
+
+ {/* Application footer */}
+
+
+
+
+```
+
+## λ¨μΌ μ±
μ μ»΄ν¬λνΈλ‘ 리ν©ν°λ§ νκΈ°
+
+λ§μ½ μ¬λ¬λΆμ μ ν리μΌμ΄μ
μ΄ λ§μ νλ©΄ νΉμ λ§μ λͺ¨λ¬μ ν¬ν¨νκ³ μλ€λ©΄, μλ₯Ό λ€μ΄ ScreenSwitchboard.jsxμ ModalManager.jsxμ κ°μ΄ λΌμ°νΈμ λͺ¨λ¬μ λ³λμ μ»΄ν¬λνΈλ‘ μΆμΆν¨μΌλ‘μ¨ AppShell.jsx μ»΄ν¬λνΈλ₯Ό μ’ λ κΉλνκ² λ§λ€ μ μμ΅λλ€.
+
+```tsx
+import React, { useState } from "react";
+import { BrowserRouter } from "react-router-dom";
+
+import AppHeader from "./AppHeader";
+import AppFooter from "./AppFooter";
+
+import ScreenSwitchboard from "./ScreenSwitchboard";
+import ModalManager from "./ModalManager";
+
+import "./app-shell.css";
+
+const AppShell = () => {
+ const [modalOpen, setModal] = useState(false);
+
+ const openModal = (event) => {
+ event.preventDefault();
+ const {
+ target: {
+ dataset: { modal },
+ },
+ } = event;
+ if (modal) setModal(modal);
+ };
+
+ const closeModal = () => {
+ setModal("");
+ };
+
+ return (
+
+
+
+ );
+};
+
+export default AppShell;
+```
+
+## μ΄λ²€νΈ λ²λΈλ§μ μ¬μ©νμ¬ νΉμ λͺ¨λ¬ μ΄κΈ°
+
+μ°λ¦¬λ #app--shell μμμμ λ²λΈλ§λ ν΄λ¦ μ΄λ²€νΈλ₯Ό μΊ‘μ²ν©λλ€. νΉμ λͺ¨λ¬μ μ΄λλ‘ νΈλ¦¬κ±°νλ μ΄λ²€νΈ νΈλ€λ¬ openModalμ μ°λ¦¬ μ ν리μΌμ΄μ
μ μΌλΆ μμ(λ²νΌ, λ§ν¬ λ±)μ μ€μ ν μ μλ data-modal μμ±μ μ°Ύμ΅λλ€.
+
+μλλ ν΄λ¦νμ λ λͺ¨λ¬μ μ΄λλ‘ νΈλ¦¬κ±°νλ λ²νΌμ΄ μλ νλ©΄ μ»΄ν¬λνΈμ μμμ
λλ€.
+
+```tsx
+import React from "react";
+
+const ScreenOne = ({}) => {
+ return (
+
+ Screen One
+
+
+
+
+
+
+
+ );
+};
+
+export default ScreenOne;
+```
+
+보μλ€μνΌ, μ°λ¦¬λ μ ν리μΌμ΄μ
μ κ³μΈ΅ ꡬ쑰 props λ΄λ¦¬κΈ°λ₯Ό ν΅ν΄ ν¨μλ κ°μ μ λ¬νκ³ μμ§ μμ΅λλ€. λμ , data-modal μμ±κ³Ό μ΄λ²€νΈ λ²λΈλ§μ μμ‘΄νμ¬ νΉμ λͺ¨λ¬μ μ¬λ κ²μ μ²λ¦¬ν©λλ€.
+
+## ModalManager
+
+μ°λ¦¬μ μ»΄ν¬λνΈλ λ κ°μ§ propsλ₯Ό μꡬν©λλ€: μ΄λ€ λͺ¨λ¬μ΄ μ΄λ €μΌ νλμ§λ₯Ό μ€λͺ
νλ modal propμΌλ‘μμ μν κ°κ³Ό, μ΄λ € μλ λͺ¨λ¬μ λ«λλ‘ μ ν리μΌμ΄μ
μ ν¨κ³Όμ μΌλ‘ μ§μνλ closeFn propμ
λλ€.
+
+μ°Έκ³ : λͺ¨λ¬μ κ°λ¨ν μ½ν
μΈ λ₯Ό ν¬ν¨ν μλ μκ³ , νΌ μ²λ¦¬μ κ°μ λ 볡μ‘ν κ²½μ°λ₯Ό λ€λ£° μλ μμ΅λλ€. μ°λ¦¬λ κ·Έλ€μ λ«νμ μ²λ¦¬νκΈ° μν΄ ν΄λ¦ μ΄λ²€νΈ λ²λΈλ§μ μμ‘΄νκ³ μΆμ§ μμ΅λλ€. μ¬κΈ°μμ propμ μ¬μ©νλ κ²μ΄ λ κ°λ¨νκ³ μ μ°ν©λλ€.
+
+λ€μμ μ»΄ν¬λνΈμ
λλ€.
+
+```tsx
+import React from "react";
+
+import ModalOne from "./components/common/modal-one/ModalOne";
+import ModalTwo from "./components/common/modal-two/ModalTwo";
+import ModalThree from "./components/common/modal-three/ModalThree";
+
+const ModalManager = ({ closeFn = () => null, modal = "" }) => (
+ <>
+
+
+
+
+
+ >
+);
+
+export default ModalManager;
+```
+
+## React Portalμ μ¬μ©νμ¬ λͺ¨λ¬ λ λλ§νκΈ°
+
+ν λ²μ νλμ Modalλ§ νμνλ κ²μ΄ κ°μ₯ μΌλ°μ μΈ ν¨ν΄μ΄λ―λ‘, μμ μμλ₯Ό React ν¬νΈλ‘ λ λλ§ν λνΌ μ»΄ν¬λνΈλ₯Ό λ§λλ κ²μ΄ νλΉνλ€κ³ μκ°ν©λλ€.
+
+λ€μμ src/components/common/modal/Modal.jsx μ»΄ν¬λνΈμ μ½λμ
λλ€.
+
+```tsx
+import React, { useEffect } from "react";
+import ReactDOM from "react-dom";
+
+const modalRootEl = document.getElementById("modal-root");
+
+const Modal = ({ children, open = false }) => {
+ if (!open) return null;
+
+ return ReactDOM.createPortal(children, modalRootEl);
+};
+
+export default Modal;
+```
+
+μ°λ¦¬λ #modal-root μμκ° document μ΄λκ°μ, νΉν μ ν리μΌμ΄μ
μ΄ λ§μ΄νΈλ #app-root μμμ νμ μμλ‘μ μ‘΄μ¬νκΈ°λ₯Ό κΈ°λν©λλ€.
+
+μλ₯Ό λ€μ΄, index.htmlμ
+
+
+
+```
+
+λ§μ§λ§μΌλ‘, νΉμ λͺ¨λ¬ μ»΄ν¬λνΈμ μμμ
λλ€.
+
+```tsx
+import React from "react";
+
+import Modal from "../modal/Modal";
+
+const ModalOne = ({ closeFn = () => null, open = false }) => {
+ return (
+
+
+
+
+
+
Modal One content will be rendered here.
+
+
+
+
+
+ );
+};
+
+export default ModalOne;
+```
+
+μ΄ κΈμμλ ꡬ체μ μΈ μμλ₯Ό λ€λ©΄μ μλμ μΌλ‘ μ§§κ³ κ°λ¨νκ² λ§λ€κ³ μ λͺ¨λ λ΄μ©μ λ€λ£¨μ§ μμμ΅λλ€. μ€νμΌλ§, μ κ·Όμ± κ·Έλ¦¬κ³ μλ§λ λ€λ₯Έ μμλ€μ κ³ λ €ν΄μΌ ν κ²μ
λλ€.
+
+μ΄ κΈμ 맨 μμ κ²μλ λ§ν¬μμ μ΄ μμ€ μ½λλ₯Ό μ°Ύμ μ μμ΅λλ€.
+
+λκΈλ‘ μ΄ κΈμ λν΄ μ΄λ»κ² μκ°νλμ§, νΉμ μ¬λ¬λΆμ μ ν리μΌμ΄μ
μμ λͺ¨λ¬μ μ΄λ»κ² κ΄λ¦¬νκ³ μλμ§ μλ €μ£ΌμΈμ.