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은 모달 창 콘텐츠로 한정됩니다. 간단히 말해서 이것은 새로운 구성 요소 Trigger 및 Window를 Modal의 속성으로 선언함으로써 달성할 수 있습니다. 이들은 React 하위 구성 요소입니다. 그런 것 :

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


    이전 구현에 따라 Trigger 및 Window는 열기/닫기 버튼을 표시해야 합니다. 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;
    

    isOpen 및 setOpen를 제외하고 모달 상태의 일부입니다. 따라서 그들은 모달 자식에게 전달되어야 합니다. 복잡한 소품 드릴링. 먼저 Trigger 및 Window를 검색하기 위해 자식을 "구문 분석"해야 하기 때문에 복잡합니다. 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 첫 번째 접근 방식 사용;)

    좋은 웹페이지 즐겨찾기