react-detect-click-outside 사용해보기

김은서·2024년 6월 28일
0

TIL

목록 보기
52/52
post-thumbnail

인풋창

잘 보이진 않지만 오른쪽 상단의 Search바를 만들었는데
돋보기 이모티콘을 누르면 인풋 창이 열리고, 다른 곳을 클릭하면 인풋 창이 닫히는 것을 구현해보고 싶었음.

기존 코드 👇

  const [searchOpen, setSearchOpen] = useState(false);
  const toggleSearch = () => {
    if (searchOpen) {
      //trigger the close animation
      inputAnimation.start({
        scaleX: 0,
      });
    } else {
      //trigger the open animation
      inputAnimation.start({
        scaleX: 1,
      });
    }
    setSearchOpen((prev) => !prev);
  };

      <Col >
        <Search onSubmit={handleSubmit(onValid)}>
          <motion.svg
            onClick={toggleSearch}
            animate={{ x: searchOpen ? -223 : 0 }}
            transition={{ type: "linear" }}
            fill="currentColor"
            viewBox="0 0 20 20"
            xmlns="http://www.w3.org/2000/svg"
          >
            <path
              fillRule="evenodd"
              d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
              clipRule="evenodd"
            ></path>
          </motion.svg>
          <Input
            {...register("keyword", { required: true, minLength: 2 })}
            initial={{ scaleX: 0 }}
            animate={inputAnimation}
            transition={{ type: "linear" }}
            placeholder="Search for movie or tv show..."
          />
        </Search>
      </Col>

이렇게 하니까 돋보기 아이콘을 눌러야만 열리고 닫히는걸 확인함. (바깥영역 눌러도 닫히지 않음. 당연하긴 함 ㅎㅎ)

그래서 모달처럼 만들어볼까 하다가 다른 방법은 뭐가있나 궁금해짐.

그러다 react-detect-click-outside 👈 이걸 찾아냄! ㅎ

  1. 설치
npm i react-detect-click-outside
  1. import 하기
import { useDetectClickOutside } from 'react-detect-click-outside';
  1. 예시코드확인
const Dropdown = ({ closeDropdown }) => {
  const ref = useDetectClickOutside({ onTriggered: closeDropdown });
  return (
    <div className="dropdown" ref={ref}>
      <p>This is a dropdown!</p>
    </div>
  );
};
  1. 내 코드에 대입해보기
  const [searchOpen, setSearchOpen] = useState(false);
  const toggleSearch = () => {
    if (searchOpen) {
      //trigger the close animation
      inputAnimation.start({
        scaleX: 0,
      });
    } else {
      //trigger the open animation
      inputAnimation.start({
        scaleX: 1,
      });
    }
    setSearchOpen((prev) => !prev);
  };

//  추가 코드 
  const closeSearch = () => {
    inputAnimation.start({
      scaleX: 0,
    });
    setSearchOpen(false);
  };

  const ref = useDetectClickOutside({
    onTriggered: closeSearch,
  });
      <Col ref={ref}> //  추가 코드 
        <Search onSubmit={handleSubmit(onValid)}>
          <motion.svg
            onClick={toggleSearch}
            animate={{ x: searchOpen ? -223 : 0 }}
            transition={{ type: "linear" }}
            fill="currentColor"
            viewBox="0 0 20 20"
            xmlns="http://www.w3.org/2000/svg"
          >
            <path
              fillRule="evenodd"
              d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
              clipRule="evenodd"
            ></path>
          </motion.svg>

          <Input
            {...register("keyword", { required: true, minLength: 2 })}
            initial={{ scaleX: 0 }}
            animate={inputAnimation}
            transition={{ type: "linear" }}
            placeholder="Search for movie or tv show..."
          />
        </Search>
      </Col>

돋보기 아이콘을 누르면 잘 열리고 , 잘 닫힘.

게다가 인풋 바깥영역을 클릭해도 잘 닫힘!

생각보다 너무 간단하다 ㅎㅎ
인풋창 말고도 다른 모달에 사용해도 편리할듯!!

0개의 댓글