언어/Next.js

[Next 고캠핑] 커스텀훅으로 alert창 만들기

홍시_코딩기록 2024. 7. 27. 23:48

아직 준비중인 기능 alert창

 

아직 준비중인 기능들이 있어 alert창을 띄우는데 커스텀을 하고싶었고,

여러 화면에서 사용할 것이기 때문에 컴포넌트화해서 사용하고 싶었다.

 

 

방법을 찾아본 결과 이 방법이 제일 간단하고 편리한거 같아서 따라하게 되었다.

 

hooks/useModal.ts

import { useState } from "react";

export function useModal() {
  const [isShowing, setIsShowing] = useState(false);

  const modalToggle = () => {
    setIsShowing(!isShowing);
  };

  return {
    isShowing,
    modalToggle,
  };
}

- useModal 커스텀 훅을 만들어서 모달이 보이는 상태와 모달 토글 이벤트를 넘겨주었다.

 

component/Modal

interface IPropsModal {
  isShowing: boolean;
  hide: () => void;
  message: string;
}

export function Modal({ isShowing, hide, message }: IPropsModal) {
  return isShowing
    ? ReactDOM.createPortal(
        <Wrap onClick={hide}>
          <ModalInner
            className="modal"
            onClick={(e: React.MouseEvent<HTMLDivElement>) => {
              e.stopPropagation();
            }}
          >
            <div>
              <AlertIcon />
              <p>{message}</p>
            </div>
            <Button onClick={hide}>닫기</Button>
          </ModalInner>
        </Wrap>,
        document.body,
      )
    : null;
}

ReactDOM.createPortal로 모달창을 document.body에 넣어준다.

createPortal은 root가 아닌 다른 곳에서 렌더링 할 수 있게 해준다.

ReactDOM.createPortal(child, container)

첫 번째 인자는 컴포넌트, 두번째 인자는 컴포넌트가 들어갈 곳

 

나는 모달창이기 때문에 document.body에 넣었다.

 

 

** 사용 **

export default function Home() {
  const { showAlert, onCloseSearchAlret, onChangeSearch, onClickSearch } =
    useSearch(); // 코드 중복으로 useSearch 커스텀 훅으로 수정
  const { isShowing, modalToggle } = useModal();

  return (
    <>
      <Head>
        <title>Go Camping</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <Wrap>
        <MainWrap>
          <Button
            onClick={() => {
              modalToggle();
            }}
            className="review"
          >
            요즘 캠핑 후기 보기
          </Button>
          {/* 캠핑 후기 준비중 alert */}
          <Modal
            isShowing={isShowing}
            hide={modalToggle}
            message="준비 중입니다!"
          />
          <SearchBox>
            <h2>Dayily camping</h2>
            <div className="search">
              <DropDown isMain={true} onChangeSearch={onChangeSearch} />
              <Button onClick={onClickSearch} className="search_btn">
                <span className="mobile">검색하기</span>
                <span className="sr_only">검색</span>
              </Button>
            </div>
          </SearchBox>
          {/* 지역 미선택시 alert */}
          {showAlert && (
            <Modal
              isShowing={showAlert}
              hide={onCloseSearchAlret}
              message="지역을 선택해주세요!"
            />
          )}
        </MainWrap>
      </Wrap>
    </>
  );
}

지역 미선택 alert은 useSearch 훅으로 만들어놨었기 때문에 코드 수정을 했다.

 


useSearch() 수정 코드

더보기

export function useSearch() {
  const [region, setRegion] = useState<string>("");
  const [subRegion, setSubRegion] = useState<string | null>(null);
  const router = useRouter();
  const [showAlert, setShowAlert] = useState<boolean>(false);

  const onChangeSearch = (region: string, subRegion: string | null) => {
    setRegion(region);
    setSubRegion(subRegion);
  };

  const onClickSearch = async (): Promise<void> => {
    if ((region !== null && subRegion !== null) || region === "전체") {
      await router
        .push({
          pathname: "/campingList",
          query: { region, subRegion },
        })
        .catch((error) => {
          console.log(error);
        });
    } else {
      setShowAlert(true);
    }
  };

  const onCloseSearchAlret = () => {
    setShowAlert(false); // 모달 닫기
  };
  return {
    showAlert,
    region,
    subRegion,
    onCloseSearchAlret,
    onChangeSearch,
    onClickSearch,
  };
}

 

https://kimyk60.tistory.com/38

 

[React] 커스텀 훅을 사용한 DefualtModal 만들기

커스텀 훅을 사용해 defultModal을 제작해보자. 코드 확인하기 커스텀 훅 생성하기 먼저 커스텀 훅'useModal.js'의 코드는 다음과 같다. import { useState } from "react"; const useModal = () => { const [isShowing, setIsSho

kimyk60.tistory.com