고유한 "useModal"Hook & Context API가 있는 다음 React Modal.

안녕하세요 여러분, 이것은 Hooks, Context 및 Portal을 결합한 React 프로젝트에서 Modals 구성 요소를 사용하는 방법에 대한 빠른 검토입니다. React로 코딩한 경험이 있어야 하고 Hooks 및 Context API와 같은 React의 최신 업데이트에 대해 알고 있어야 합니다. 해보자

모달 컴포넌트



Modal Component를 작성하기 전에 public/index.html(또는 JS 코드를 렌더링하는 HTML)을 열고 React Portal을 사용하여 Modal Component를 렌더링하는 새 태그를 추가하겠습니다.

<body>
  <noscript>
    You need to enable JavaScript to run this app.
  </noscript>
  <div id="modal-root"></div>
  <div id="root"></div>
</body>


이제 Modal Component를 작성하고 createPortal 함수를 사용합니다. createPortal 함수는 두 개의 매개변수를 예상합니다. 첫 번째는 실제 JSX이고 두 번째는 이를 렌더링할 DOM 요소입니다.

import React from "react";
import ReactDOM from "react-dom";

const Modal = () => {
  return ReactDOM.createPortal(
    <div
      className="fixed top-0 left-0 h-screen w-full flex items-center justify-center"
      style={{ background: "rgba(0,0,0,0.8)" }}
    >
      <div className="bg-white relative p-5 shadow-lg rounded flex flex-col items-start text-lg text-gray-800">
        <button
          className="absolute top-0 right-0 -mt-12 font-bold self-end rounded-full bg-red-200 mb-3 bg-white text-red-700 w-8 h-8"
          onClick={() => {}}
        >
          &times;
        </button>
        <p>I am the Modal</p>
      </div>
    </div>,
    document.querySelector("#modal-root")
  );
};

export default Modal;



useModal Hook



이 사용자 정의 Hook은 Modal Component 상태를 유지하지만 먼저 react 문서에 따라 Hook이 무엇인지 상기시켜 보겠습니다.

React Hooks are functions that let us hook into the React state and lifecycle features from function components. By this, we mean that hooks allow us to easily manipulate the state of our functional component without needing to convert them into class components



다시 말해, Hooks를 사용하면 상태의 "공유 가능한 모델"과 이러한 상태를 조작하는 메서드를 만들 수 있습니다. 두 가지를 모두 반환하면 구성 요소 간에 재사용할 수 있고 프로젝트에서 코드 중복을 피할 수 있습니다. 동일한 상태 구조와 메서드를 초기화하는 구성 요소가 두 개 이상 있는 경우 사용자 정의 후크에서 이를 추출하는 것이 좋습니다. 상태와 메서드를 한 곳에 모아 재사용할 수 있습니다. 이것은 우리의 커스텀 useModal React Hook입니다.

import React from "react";

export default () => {
  let [modal, setModal] = React.useState(false);
  let [modalContent, setModalContent] = React.useState("I'm the Modal Content");

  let handleModal = (content = false) => {
    setModal(!modal);
    if (content) {
      setModalContent(content);
    }
  };

  return { modal, handleModal, modalContent };
};



일반적으로 우리가 만드는 모든 Hook은 "use"라는 단어로 시작해야 합니다.
이제 Hooks를 사용하여 구성 요소 간에 실제 상태 값을 공유할 수 있다고 생각할 수 있습니다. 슬프게도 대답은 NO입니다. 구성 요소에서 Hook을 사용하고 Hooks에서 상태를 추출할 때마다 이는 "로컬 상태"만 표시됩니다. 해당 구성 요소 내에서 실제 상태를 자식 구성 요소에 전달하려면 props를 통해 또는 이 경우에는 React Context를 사용하여 수행해야 합니다.

반응 컨텍스트



ModalContext에서 새로 생성된 React Hook을 사용할 것입니다...

import React from "react";
import useModal from "./useModal";
import Modal from "./modal";

let ModalContext;
let { Provider } = (ModalContext = React.createContext());

let ModalProvider = ({ children }) => {
  let { modal, handleModal, modalContent } = useModal();
  return (
    <Provider value={{ modal, handleModal, modalContent }}>
      <Modal />
      {children}
    </Provider>
  );
};

export { ModalContext, ModalProvider };


이제 컨텍스트 정보를 소품으로 사용하기 시작하도록 모달 구성 요소에서 간단한 수정을 수행해 보겠습니다.

import React from "react";
import ReactDOM from "react-dom";
import { ModalContext } from "./modalContext";

const Modal = () => {
  let { modalContent, handleModal, modal } = React.useContext(ModalContext);
  if (modal) {
    return ReactDOM.createPortal(
      <div
        className="fixed top-0 left-0 h-screen w-full flex items-center justify-center"
        style={{ background: "rgba(0,0,0,0.8)" }}
      >
        <div className="bg-white relative p-5 shadow-lg rounded flex flex-col items-start text-lg text-gray-800">
          <button
            className="absolute top-0 right-0 -mt-12 font-bold self-end rounded-full bg-red-200 mb-3 bg-white text-red-700 w-8 h-8"
            onClick={() => handleModal()}
          >
            &times;
          </button>
          <p>{modalContent}</p>
        </div>
      </div>,
      document.querySelector("#modal-root")
    );
  } else return null;
};

export default Modal;



이제 app.js 구성 요소로 이동하고 Modal 구성 요소와 컨텍스트 공급자를 사용하기 시작하겠습니다.

import React from "react";
import { ModalProvider } from "./modalContext";
import Component from "./component";
import Component2 from "./component2";

export default function App() {
  return (
    <div className="App container mx-auto px-8 text-gray-700">
      <h1 className="text-3xl">Hello CodeSandbox</h1>
      <h2 className="text-xl mb-6">Start editing to see some magic happen!</h2>
      <ModalProvider>
        <Component />
        <Component2 />
      </ModalProvider>
    </div>
  );
}


"Component 및 Component2"에 몇 가지 구성 요소가 있음을 알 수 있습니다. 이 구성 요소는 모달을 여는 버튼을 보유하는 일부 더미 구성 요소입니다. 이들 간의 주요 차이점은 모달 내부에서 렌더링할 메시지입니다.

import React from "react";
import { ModalContext } from "./modalContext";

const Component = () => {
  let { handleModal } = React.useContext(ModalContext);

  return (
    <>
      <p>
        Lorem ipsum dolor sit amet consectetur, adipisicing elit. Cumque quidem
        asperiores?
      </p>
      <button
        className="mt-6 rounded  bg-purple-700 text-purple-100 px-5 h-12"
        onClick={() => handleModal("This is component modal content")}
      >
        open this modal!
      </button>
    </>
  );
};

export default Component;


이런 식으로 끝낼 것입니다 CodeSandbox Modal Demo

그게 다야, 나는 코드의 특정 부분을 파헤치지 않고 가능한 한 짧게 만들려고 노력했다. 코드나 다른 접근 방식에 대해 의심이 가는 부분이 있으면 댓글로 알려주세요.

사진 작성자Rodolpho Zanardo, Pexels

Rhys Nicholls의 경우 "내부에서 모달 닫기"
문자열 대신 handleModal 함수에 구성 요소를 전달할 수 있습니다. 그런 다음 해당 구성 요소에서 컨텍스트에서 handleModal 함수를 구조화하고 다음과 같이 요청 시 해당 함수를 호출할 수 있습니다.
요소

function ContentComponent() {
  let { handleModal } = React.useContext(ModalContext);
  return (
    <>
      <p>Hello here !!!</p>
      <button
        className="h-8 px-3 text-white bg-red-500 text-xs rounded"
        onClick={handleModal}
      >
        Close modal
      </button>
    </>
  );
}



그런 다음이 구성 요소를 가져 와서 handleModal에서 사용하십시오.

const Component = () => {
  let { handleModal } = React.useContext(ModalContext);

  return (
    <>
      <p>
        Lorem ipsum dolor sit amet consectetur, adipisicing elit. Cumque quidem
        asperiores?
      </p>
      <button
        className="mt-6 rounded  bg-purple-700 text-purple-100 px-5 h-12"
        onClick={() => handleModal(<ContentComponent />)}
      >
        open this modal!
      </button>
    </>
  );
};



여기에서 라이브 예제를 볼 수 있습니다https://codesandbox.io/s/eloquent-hamilton-vgbyq?file=/src/component.js:75-508https://codesandbox.io/s/eloquent-hamilton-vgbyq?file=/src/component.js:75-508.

Joel Robles Bentham의 경우 "페이지 로드 시 모달 열기"
구성 요소 마운트, 사용 및 효과에서 간단하게 호출하십시오.

// the string could be a component as as well
 React.useEffect(() => {
    handleModal("This is component 2 modal content on page load");
  }, []);


여기 라이브 예제https://codesandbox.io/s/eloquent-hamilton-vgbyq?file=/src/component2.js:160-261

좋은 웹페이지 즐겨찾기