[React] 외부 영역 클릭시 모달 창 닫기

박세화·2023년 6월 5일

React JS

목록 보기
4/22

그냥 남의 글 보고 코드 베꼈는데....잘 동작한다...
왜지...?
아무튼 굿 😶

+토글 아니고 모달 창이라고 해야 하는 것 알지만 귀찮아서 코드 수정 안했음

const Toggle = () => {
  const [isToggleClicked, setIsToggleClicked] = useState(false);
  const inSection = useRef();

  const onClick = () => {
    setIsToggleClicked((prev) => !prev);
  };

  useEffect(() => {
    const clickOutside = (e) => {
      if (
        isToggleClicked &&
        !inSection.current.contains(e.target)
      ) {
        setIsToggleClicked(false);
      }
    };

    document.addEventListener("mousedown", clickOutside);

    return () => {
      document.removeEventListener("mousedown", clickOutside);
    };
  }, [isToggleClicked]);

  return (
    <StyledDiv ref={inSection} className="toggle-box">
      <button className="toggle-button" onClick={onClick}>
        <RxHamburgerMenu />
      </button>
      {isToggleClicked && <ToggleContents />}
    </StyledDiv>
  );
};

export default Toggle;
  • toggle box 전체를 ref로 만듦.

  • isToggleClicked가 true이면서 && inSection.current(=toggle box div)가 e.target(클릭된 부분)을 포함하지 않을시 isToggleClicked를 false로 바꿈 (=토글 닫기)

  • 컴포넌트가 언마운트될 때 이벤트리스너를 삭제하는 코드를 작성했으나 이 컴포넌트는 화면에 항상 있는 애라서 딱히 소용 X...



useRef

이 블로그가 정리가 잘 돼있어서 많이 참고했다.

자바스크립트에서 querySelector로 DOM 요소를 직접 선택하는 것처럼, 리액트에서는 DOM 요소 선택시 useRef 라는 React Hook을 사용한다.

📌 useRef로 DOM 요소를 선택할 수 있다.

const inputRef = useRef();

function focus() {
   inputRef.current.focus();
   console.log(inputRef.current);
}

return (
    <div>
      <input ref={inputRef} type="text" placeholder="아이디 또는 이메일" />
      <button>Login</button>
      <br />
      <button onClick={focus}>focus</button>
    </div>
);

input 태그를 ref로 만들면, inputRefcurrentinput 태그가 된다.


이 외 또 다른 사용법

📌 useRef로 관리하는 변수는 값이 변해도 화면에 렌더링되지 않는다.
useEffect안에서의 set state 변경 때문에 무한루프에 빠질 때 효율적으로 해결할 수 있는 방법 중 하나가 된다.



❓ _미해결된 부분) `useEffect`의 dependency로 `isToggleClicked`를 넣어줬는데 대체 왜 뭐 클릭할 때마다 실행될까_

0개의 댓글