React에서 Modal을 수행하는 방법: HTML 첫 번째 접근 방식

16931 단어 javascripthtmlreact
CSS, JS... 또는 React를 하기 전에 HTML을 하세요.

먼저 모달이 있었다



이 이야기는 모달에서 시작되었습니다. React 프로젝트에 모달 창이 필요했습니다. 다음은 wikipedia의 좋은 정의입니다.

A modal window creates a mode that disables the main window but keeps it visible, with the modal window as a child window in front of it. Users must interact with the modal window before they can return to the parent application.



React를 사용하면 다음과 같은 형식을 취할 수 있습니다.

<Modal trigger={<button type="button">Click me</button>}>
  Lorem ipsum in a modal
</Modal>

Modal 구성 요소의 첫 번째 구현:

function Modal({ trigger, children }) {
  const [isOpen, setOpen] = useState(false);

  return (
    <>
      {React.cloneElement(trigger, {
        onClick: () => setOpen(true)
      })}
      {isOpen && (
        <div>
          <button
            type="button"
            onClick={() => setOpen(false)}>
            x
          </button>
          <div>{children}</div>
        </div>
      )}
    </>
  );
}


모달 로직과 시맨틱에 집중하기 위해 클래스 이름과 스타일을 제거했습니다. 이것이 첫 번째 문제입니다. 의미 체계입니다.

모달은 트리거와 모달 창의 내용으로 구성됩니다. 콘텐츠가 "모달 창"콘텐츠로 한정되지 않는 경우를 제외하고. 또한 이Modal는 다양한 메커니즘을 통해 트리거와 콘텐츠를 처리합니다.
  • 트리거는 요소(컨테이너 + 콘텐츠: 여기에서는 "클릭하세요"텍스트가 있는 <button>)를 기다리는 소품입니다.
  • lorem ipsum은 렌더링 노드로 전달되는 구성 요소의 내용입니다(내용만: Modal가 텍스트를 <div>로 감쌉니다).

  • 그리고 하위 구성요소가 있었습니다.



    보다 의미 있고 일관된 버전은 다음과 같습니다.

    <Modal>
      <Modal.Trigger>Click me</Modal.Trigger>
      <Modal.Window>
        Lorem ipsum in a modal
      </Modal.Window>
    </Modal>
    


    여기서 트리거와 창은 동일한 수준에 있으며 lorem ipsum은 모달 창 콘텐츠로 한정됩니다. 간단히 말해서 이것은 새로운 구성 요소 TriggerWindowModal의 속성으로 선언함으로써 달성할 수 있습니다. 이들은 React 하위 구성 요소입니다. 그런 것 :

    function Modal(/* ... */) {
      /* ... */
    }
    
    function Trigger(/* ... */) {
      /* ... */
    }
    
    Modal.Trigger = Trigger;
    
    function Window(/* ... */) {
      /* ... */
    }
    
    Modal.Window = Window;
    


    이전 구현에 따라 TriggerWindow는 열기/닫기 버튼을 표시해야 합니다. Modal은 컨테이너이며 자식을 표시해야 합니다.

    function Modal({ children }) {
      const [isOpen, setOpen] = useState(false);
    
      return (
        <>
          {children}
        </>
      );
    }
    
    function Trigger({ children }) {
      /* ... */
    
      return (
        <button
          type="button"
          onClick={() => setOpen(true)}>
          {children}
        </button>
      );
    }
    
    Modal.Trigger = Trigger;
    
    function Window({ children }) {
      /* ... */
    
      return isOpen && (
        <div>
          <button
            type="button"
            onClick={() => setOpen(false)}>
            x
          </button>
          {children}
        </div>
      );
    }
    
    Modal.Window = Window;
    

    isOpensetOpen를 제외하고 모달 상태의 일부입니다. 따라서 그들은 모달 자식에게 전달되어야 합니다. 복잡한 소품 드릴링. 먼저 TriggerWindow를 검색하기 위해 자식을 "구문 분석"해야 하기 때문에 복잡합니다. Context API를 사용하여 쉽게 해결해 보겠습니다.

    const ModalContext = createContext();
    
    function Modal({ children }) {
      const [isOpen, setOpen] = useState(false);
    
      return (
        <ModalContext.Provider value={{ isOpen, setOpen }}>
          {children}
        </ModalContext.Provider>
      );
    }
    
    function Trigger({ children }) {
      const { setOpen } = useContext(ModalContext);
    
      return (
        <button
          type="button"
          onClick={() => setOpen(true)}>
          {children}
        </button>
      );
    }
    
    Modal.Trigger = Trigger;
    
    function Window({ children }) {
      const { isOpen, setOpen } = useContext(ModalContext);
    
      return isOpen && (
        <div>
          <button
            type="button"
            onClick={() => setOpen(false)}>
            x
          </button>
          {children}
        </div>
      );
    }
    
    Modal.Window = Window;
    


    어쩜 이렇게 이쁘니! 아니면 정말입니까?

    HTML의 첫 번째 접근 방식



    그랬다. 진짜. 이러한 아름다움은 오래 전에 HTML에 추가되었습니다. 열림/닫힘 상태가 있는 요소로 자식에 의해 트리거되고 콘텐츠 표시를 제어합니다. <details><summary> 태그가 있습니다. 그들은 우리Modal를 다음과 같이 만듭니다.

    function Modal({ children }) {
      return <details>{children}</details>;
    }
    
    function Trigger({ children }) {
      return <summary>{children}</summary>;
    }
    
    Modal.Trigger = Trigger;
    
    function Window({ children }) {
      return <div>{children}</div>;
    }
    
    Modal.Window = Window;
    


    일부 스타일이 포함된 전체 데모는 여기에서 볼 수 있습니다: https://codepen.io/rocambille/pen/poaoKYm .

    때때로 우리는 무언가를 원합니다. 그리고 때때로 우리는 그것들을 너무 원해서 코드를 작성하기 시작합니다. JS 또는 다른 언어/도구/프레임워크를 사용합니다. 그것이 우리가 배운 것이기 때문입니다. 가능한 경우 순수한 CSS를 사용합니다.

    때때로 우리는 CSS나 JS... 또는 React를 하기 전에 HTML을 해야 합니다. HTML 첫 번째 접근 방식 사용;)

    좋은 웹페이지 즐겨찾기