ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [고양이 사진 검색 사이트] - 이미지 상세 보기 모달 : 모달, keypress, fade in/out
    React/과제 테스트 2023. 8. 7. 13:41
    반응형

    프로그래머스 과제 테스트 준비

    프로그래머스는 html,css, javaScript이기 때문에 실질적으로 도움이 될 만한 React로 준비했다. 

    테스팅에 목적이 아닌 학습을 위한 구현자료로써, 디자인은 하지 않았고 기능에 초점을 두었다. 

     

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

    🐇이미지 상세보기 모달

     

    🥕 max-size가 768px 이하인경우 모달의 가로길이를 디바이스 가로길이만큼 늘림

    1. modal 창 구현

    <ModalOverlay onClick={onClose}>
          <ModalContent onClick={(e) => e.stopPropagation()} isOpen={isOpen}>
            {isLoading ? (
              <p>로딩중</p>
            ) : (
              <>
                <Button onClick={onClose}>x</Button>
                {catDetail && (
                  <>
                    <img
                      src={catDetail.url}
                      style={{ width: 400, height: 400 }}
                      alt={catDetail.id}
                      loading="lazy"
                    />
                    <h5>{catDetail.name}</h5>
                    <p>temperament : {catDetail.temperament}</p>
                    <p>origin: {catDetail.origin} </p>
                  </>
                )}
              </>
            )}
          </ModalContent>
        </ModalOverlay>

    2. style 구현 - media query 구현

     

    const ModalOverlay = styled.div`
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      display: flex;
      justify-content: center;
      align-items: center;
    `;

    const ModalContent = styled.div`
      @media (max-width: 768px) {
        width: 100vw;
      }

      @media (max-width: 992px) {
        width: 540px;
        height: 613.34px;
      }

      background-color: #fff;
      padding: 20px;
      border-radius: 8px;

      /*  모달 열고 닫기에 fade in/out을 적용 */
      opacity: ${({ isOpen }) => (isOpen ? 1 : 0)};
      pointer-events: ${({ isOpen }) => (isOpen ? 'auto' : 'none')};
      transition: opacity 0.3s ease-in-out;
    `;

    const Button = styled.button`
      background-color: transparent;
      width: 100px;
      height: 40px;
      margin-left: 80%;
    `;
     

     

    🥕 이미지 클릭 시 생성된 모달에서 다음 종료(닫힘) 이벤트를 추가한다.

    [닫기 클릭 조건] 
     - 키보드의 esc를 누를 때
    - 모달 영역밖을 클릭할 때
    - 우측 상단의 닫기를 클릭할 때

    0. modal props로 모달 닫는 함수 전달

    <Modal
                isOpen={isModalOpen}
                onClose={() => setIsModalOpen(false)}
                id={currentCat}
              />

    1. modal 외부 영역 클릭시 

    <ModalOverlay onClick={onClose}>

    2. 키보드의 esc를 누를 때

    // ESC 키를 누르면 모달이 닫히도록 이벤트 리스너 추가
      useEffect(() => {
        const handleKeyPress = (e) => {
          if (e.key === 'Escape') {
            onClose();
          }
        };
        setCatDetail([]);
        window.addEventListener('keydown', handleKeyPress);

        return () => {
          window.removeEventListener('keydown', handleKeyPress);
        };
      }, [onClose]);

    3. 우측 상단 닫기 클릭시

    <Button onClick={onClose}>x</Button>

    🥕 /cats/:id를 통해 고양이의 성격, 태생정보를 렌더링한다. 해당정보는 불러온다.

    1. 고양이 사진 클릭 시 modal 창 구현

    // 모달 보여주는 함수
      const displayModal = async (id) => {
        setIsModalOpen(true);
        setCurrentCat(id);
      };
    <S.Img
                    loading="lazy"
                    src={v.url}
                    key={i}
                    alt={v.id}
                    title={v.name}
                    onClick={() => displayModal(v.id)}
                  />

     

    2. 고양이 상세정보 가져오기

    // 컴포넌트가 렌더링된 후에 상세 정보를 가져옴
      useEffect(() => {
        if (isOpen) {
          getDetail(id);
          console.log('isOpen', isOpen);
        }
      }, [id, isOpen]);

     

    3. modal 창에 정보 보여주기

     {catDetail && (
                  <>
                    <img
                      src={catDetail.url}
                      style={{ width: 400, height: 400 }}
                      alt={catDetail.id}
                      loading="lazy"
                    />
                    <h5>{catDetail.name}</h5>
                    <p>temperament : {catDetail.temperament}</p>
                    <p>origin: {catDetail.origin} </p>
                  </>
                )}

     

    🥕 Modal의 열기/닫기 이벤트에 fade in/out 적용

     

    const ModalContent = styled.div`

      /*  모달 열고 닫기에 fade in/out을 적용 */
      opacity: ${({ isOpen }) => (isOpen ? 1 : 0)};
      pointer-events: ${({ isOpen }) => (isOpen ? 'auto' : 'none')};
      transition: opacity 0.3s ease-in-out;
    `;

     

    반응형
Designed by Tistory.