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

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

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

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


2021년 2월 24일 오후

useNetwork

실시간 업데이트가 필요하거나 사용자와 상호작용 해야하는 웹 사이트는 만약 인터넷 연결이 끊겼을 경우, 사용자에게 그 사실을 알려줄 필요가 있습니다.🚨 useNetwork는 이런 상황에서 간편하게 쓸 수 있는 후크입니다.

또한 인터넷 연결 여부(true, false)에 따라 동작을 수행하는 함수를 매개변수로 넘겨줄 수 있습니다(예를 들면 사용자에게 경고창을 띄우는 것 같은).

const useNetwork = (onChange) => {
    // navigator 객체로부터 온라인 여부를 받아옴
  const [isOnline, setIsOnline] = useState(navigator.onLine);
    // 온라인 여부가 바뀔 때마다 실행되는 핸들러 함수
  const handleChange = () => {
    if (typeof onChange === "function") {
      onChange(navigator.onLine);
    }
    setIsOnline(navigator.onLine);
  };
  useEffect(() => {
      // 온라인, 오프라인일 때 모두 업데이트
    window.addEventListener("online", handleChange);
    window.addEventListener("offline", handleChange);
    return () => {
      window.removeEventListener("online", handleChange);
      window.removeEventListener("offline", handleChange);
    };
  }, []);
    // 온라인 여부 반환
  return isOnline;
};

useNetwork 함수는 매개변수 onChange로 온/오프라인 상태일 때 실행할 함수를 전달받습니다. 전달하는 함수는 true, false에 따라 각각 실행할 동작이 정의되어 있어야 합니다.

isOnline state를 만들고 navigator 객체의 onLine 속성으로 초기화합니다. 이 속성은 브라우저의 온라인 여부에 따라 true or false를 반환합니다.

그리고 window 객체의 online, offline 이벤트와 연결할 핸들러 함수를 만들어줍니다. 이 함수 역시 navigator.onLine으로부터 온라인 여부를 받아 onChange 매개변수로 받은 함수와 setIsOnline에 각각 넘겨줍니다.

마지막으로 useEffect 내에서 window 객체가 온/오프라인 상태일 때의 이벤트 리스너를 달아줍니다. 그리고 컴포넌트가 언마운트되면 리스너를 제거합니다. handleChange 함수가 navigator 객체로부터 온/오프라인 상태를 직접 받기 때문에 하나의 리스너로 두 이벤트를 모두 처리할 수 있습니다!

useScroll

어떤 홈페이지에 들어가보면 스크롤을 할 때마다 배경색이 바뀐다거나🌈 애니메이션이 시작되는 경우가 있습니다. 특히 애플 홈페이지가 그런 효과를 사용한 광고를 잘 만드는데요, useScroll은 사용자의 스크롤 위치를 반환해줘서 간단하게 스크롤 효과를 만들 수 있는 후크입니다.

const useScroll = () => {
    // 스크롤 X, Y 좌표를 객체로 저장
  const [position, setPosition] = useState({
    X: 0,
    Y: 0,
  });
    // 윈도우 객체로부터 scrollX, Y를 받아옴
  const onScroll = () => {
    setPosition({
      X: window.scrollX,
      Y: window.scrollY,
    });
  };
    // 컴포넌트 렌더링 후 윈도우 객체의 리스너로 등록
  useEffect(() => {
    window.addEventListener("scroll", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
    };
  }, []);
  return position;
};

우선 setState를 이용해서 사용자의 스크롤 위치 객체를 저장합니다. 사용 범위를 넓히기 위해서 X, Y 좌표를 모두 객체에 저장했습니다.

onScrollwindow 객체의 스크롤 이벤트의 리스너입니다. 사용자가 스크롤할 때마다 window 객체로부터 스크롤 좌표를 받아와 업데이트합니다.

마지막으로 useEffect를 이용해서 side-effect로 window 객체에 이벤트 리스너를 달아줍니다. 마찬가지로 컴포넌트가 언마운트 될 때 이벤트 리스너를 제거해줍니다.

const {Y} = useScroll();
...
<h1 style={{
           "font-size": 300,
           "position": "fixed",
           "color": Y <= 500? "red":"blue"
          }}>Hello</h1>

간단한 사용 예시입니다. useScroll에서 얻은 Y좌표로 컴포넌트 내의 요소에 변화를 줄 수 있습니다. 사용자의 Y 스크롤이 500을 초과하게 되면 h1의 색이 변합니다.

useFullscreen

사진이나 동영상 같은 요소를 페이지 내에서 볼 때 전체화면으로 보여주고 싶은 경우가 있습니다. useFullscreen은 후크는 아니지만 간단하게 특정 요소를 풀 스크린으로 전환하고, 풀 스크린 상태일 때 실행할 함수를 연동시킬 수 있습니다.

const useFullscreen = (fullscreenCallback) => {
  // 대상 요소의 레퍼런스 생성
  const element = useRef();
  // 인자로 받은 콜백 함수 검사
  const runCallback = (isFull) => {
    if (fullscreenCallback && typeof fullscreenCallback === "function") {
      fullscreenCallback(isFull);
    }
  };
  const onFullscreen = () => {
    if (element.current) {
      if (element.current.requestFullscreen) {
        element.current.requestFullscreen();
      } else if (element.current.mozRequestFullscreen) {
        element.current.mozRequestFullscreen();
      } else if (element.current.webkitRequestFullscreen) {
        element.current.webkitRequestFullscreen();
      } else if (element.current.msRequestFullscreen) {
        element.current.msRequestFullscreen();
      }
    }
    // 전체화면 상태
    runCallback(true);
  };
  const offFullscreen = () => {
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.mozCancelFullscreen) {
      document.mozCancelFullscreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen();
    }
    // 전체화면 종료
    runCallback(false);
  };

  return { element, onFullscreen, offFullscreen };
};

useFullscreen 함수는 useRef를 사용해서 element 변수에 레퍼런스를 저장합니다. 이후 element를 반환해서 컴포넌트 내 요소와 연결될 수 있도록 합니다.

풀 스크린 상태를 켜고 끌 수 있는 함수인 onFullscreenoffFullscreen을 만들어줍니다. 풀 스크린의 경우 element.current의 requestFullscreen 메소드로 구현하고, 풀 스크린을 나가는 것은 document 객체의 exitFullscreen 메소드로 구현했습니다. 그리고 크로스 브라우징을 위해🌎 각 브라우저 별 메소드를 조건문 형식으로 넣었습니다.

풀 스크린 상태를 켜면 인자로 받은 함수에 true를 전달하고, 끄면 false를 전달합니다. 이때 runCallback 함수를 이용해서 인자로 받은 함수를 검사하고 실행하게 됩니다.🔍

useFullscreen은 최종적으로 element, onFullscreen, offFullscreen 을 객체로 반환합니다. 컴포넌트 내에서 전체화면으로 보여주고 싶은 요소의 ref 속성에 element를 넣고, 두 함수를 이용해서 전체화면 상태를 바꿀 수 있습니다.

오늘은 세 개의 후크에 대해 적어보았는데요, 다음 포스팅에서도 이어서 적겠습니다.😄

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

0개의 댓글