유용하게 쓸 수 있는 React Hook 만들기 2

Hyuno Choi·2021년 2월 17일
0
post-thumbnail

소스 코드: https://github.com/soonitoon/React_Hooks

이 글은 Nomad Coder"실전형 리액트 Hooks 10개" 강의를 바탕으로 작성되었습니다.


2021년 2월 17일 오전

저번에 이어서 리액트 후크 만들기 포스팅을 이어가겠습니다.😀

usePreventLeave

사용자가 페이지 내에서 중요한 작업을 하고 있을 때 실수로 페이지에서 나가거나 새로고침 되는 것을 방지하기 위해서 경고창을 띄워야 할 때가 있습니다. 그럴 때 간단하게 사용할 수 있는 후크(비슷한 것)입니다.🙃

const usePreventLeave = () => {
    // 사용자의 페이지 이탈을 막음.
  const listener = (event) => {
    event.preventDefault();
    event.returnValue = "";
  };
    // 페이지 이탈 방지 활성화
  const enablePrevent = () => {
    window.addEventListener("beforeunload", listener);
  };
    // 이탈 방지 불활성화
  const disablePrevent = () => {
    window.removeEventListener("beforeunload", listener);
  };
  return { enablePrevent, disablePrevent };
};

usePreventLeave 함수입니다. 사용자 이탈을 방지하는 핸들러 함수를 등록하는 enablePrevent와 그걸 제거하는 disablePrevent로 이루어진 간단한 구조입니다. 이 두 함수를 반환해서 컴포넌트 내에서 사용자의 페이지 이탈을 막거나 허용할 수 있습니다.

두 함수 내에서는 listener 함수를 리스너로 window 객체에 달아주는데요, 여기서 제가 모르는 beforeunload라는 이벤트가 나와 MDN을 찾아보았습니다.🔍

문서와 그 리소스가 언로드 되기 직전에 windwo에서 발생합니다. 이벤트 발생 시점엔 문서를 아직 볼 수 있으며 이벤트도 취소 가능합니다. -MDN

말 그대로 현재 창이 닫히기 직전에 발생하는 이벤트입니다. 이 이벤트를 잡으면 사용자가 페이지를 떠나기 전에 특정 동작이 일어나도록 만들 수 있습니다.

useBeforeLeave

사용자가 탭을 닫으려고 마우스를 위로 올리거나, 마우스가 화면에서 벗어났을 때 사용자를 현재 페이지에 잡아두고 싶을 때가 있습니다. useBeforeLeave는 그런 상황에서 간단하게 핸들러 함수를 document 객체의 mouseleave 이벤트와 연결시킬 수 있습니다.

const useBeforeLeave = (onLeave) => {
    // 핸들러 함수 검사
  if (typeof onLeave !== "function") {
    return;
  }
    // 마우스가 위로 벗어난 경우에만 실행
  const handle = (event) => {
    const { clientY } = event;
    if (clientY <= 0) {
      onLeave();
    }
  };
// side-effect로 리스너를 달아줌.
  useEffect(() => {
    document.addEventListener("mouseleave", handle);
      // 컴포넌트가 unMount되면리스너 제거
    return () => {
      document.removeEventListener("mouseleave", handle);
    };
  }, []);
};

useBeforeLeave는 핸들러 함수 하나를 인자로 받습니다. 그리고 이벤트 리스너와 연결할 handle이라는 함수를 만들어줍니다.
handle 함수 내에서는 mouseleave 이벤트 객체 중 clientY 속성을 가져옵니다.

clientY는 마우스가 화면 위를 통해 빠져나갔다면 언제나 0이므로 clientY가 0일 때만 인자로 받은 핸들러 함수를 실행함으로써 마우스가 화면 밑이나 옆으로 빠져나갔을 때는 실행하지 않도록 합니다.

이후 useEffect 를 사용해 document객체에 mouseleave 이벤트 리스너를 달아줍니다. 그리고 컴포넌트가 unMount되면 리스너를 제거합니다.

useFadeIn

페이지가 로딩되었을 때 특정 요소를 서서히 나타나게 하는 효과를 줄 때가 간혹 있습니다. 그럴 때 하나하나 CSS 작업을 하는 것보다 후크를 사용해 편리하게 스타일 효과를 적용할 수 있습니다.

// fade-in 지속시간, 지연시간을 인자로 받음
const useFadeIn = (duration = 2, delay = 0) => {
  if (typeof duration !== "number" || typeof delay !== "number") {
    return;
  }
    // 레퍼런스 생성
  const element = useRef();
    // 컴포넌트가 렌더링 된 직후 실행
  useEffect(() => {
    if (element) {
      const { current } = element;
        // fade-in 스타일링
      current.style.transition = `opacity ${duration}s ease-in-out ${delay}s`;
      current.style.opacity = 1;
    }
  }, []);
    // opacity: 0으로 처음에는 요소를 감춤
  return { ref: element, style: { opacity: 0 } };
};

useFadeIn 함수는 매개변수로 페이드-인 지속시간(duration)과 지연시간(delay)을 받습니다. 이렇게 함으로써 후크를 사용하는 사람이 커스텀할 수 있게 합니다. 두 매개변수 중 하나라도 자료형이 "number"가 아니라면 함수를 종료합니다.

그 다음으로 useRef()를 사용해서 효과를 적용할 요소의 레퍼런스를 생성합니다. 레퍼런스 덕분에 document 객체에서 일일히 요소를 가져오지 않고도 구현할 수 있습니다.

마지막으로 useEffect 내에서 스타일 속성을 지정해줍니다. transition 속성의 지속시간과 지연시간에는 각각 해당하는 매개변수가 들어갑니다.

useFadeIn 함수는 JSX 태그의 refstyle 속성을 담은 객체를 반환합니다.

const App = () => {
  const fadeInH1 = useFadeIn(5, 2);
  const fadeInP = useFadeIn(2, 5);
  return (
    <div className="App">
      <h1 {...fadeInH1}>Hello</h1>
      <p {...fadeInP}>loremawdawdadajk</p>
    </div>
  );
};

이렇게 반환한 객체는 태그 내에서 전개 구문을 사용하여 간단하게 사용할 수 있습니다.

오늘은 usePreventLeave, useBeforeLeave, useFadeIn 세 개의 커스텀 후크에 대해 글을 썼는데요, 나머지 후크들도 차례차례 포스팅 하겠습니다!

profile
프론트엔드 웹 개발자를 목표로 하고 있습니다.

1개의 댓글

comment-user-thumbnail
2022년 9월 28일

고마워요!!!!

답글 달기