소스 코드: https://github.com/soonitoon/React_Hooks
이 글은 Nomad Coder의 "실전형 리액트 Hooks 10개" 강의를 바탕으로 작성되었습니다.
2021년 2월 24일 오후
실시간 업데이트가 필요하거나 사용자와 상호작용 해야하는 웹 사이트는 만약 인터넷 연결이 끊겼을 경우, 사용자에게 그 사실을 알려줄 필요가 있습니다.🚨 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
은 사용자의 스크롤 위치를 반환해줘서 간단하게 스크롤 효과를 만들 수 있는 후크입니다.
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 좌표를 모두 객체에 저장했습니다.
onScroll
은 window
객체의 스크롤 이벤트의 리스너입니다. 사용자가 스크롤할 때마다 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
은 후크는 아니지만 간단하게 특정 요소를 풀 스크린으로 전환하고, 풀 스크린 상태일 때 실행할 함수를 연동시킬 수 있습니다.
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를 반환해서 컴포넌트 내 요소와 연결될 수 있도록 합니다.
풀 스크린 상태를 켜고 끌 수 있는 함수인 onFullscreen
과 offFullscreen
을 만들어줍니다. 풀 스크린의 경우 element.current의 requestFullscreen
메소드로 구현하고, 풀 스크린을 나가는 것은 document
객체의 exitFullscreen
메소드로 구현했습니다. 그리고 크로스 브라우징을 위해🌎 각 브라우저 별 메소드를 조건문 형식으로 넣었습니다.
풀 스크린 상태를 켜면 인자로 받은 함수에 true를 전달하고, 끄면 false를 전달합니다. 이때 runCallback
함수를 이용해서 인자로 받은 함수를 검사하고 실행하게 됩니다.🔍
useFullscreen
은 최종적으로 element
, onFullscreen
, offFullscreen
을 객체로 반환합니다. 컴포넌트 내에서 전체화면으로 보여주고 싶은 요소의 ref
속성에 element
를 넣고, 두 함수를 이용해서 전체화면 상태를 바꿀 수 있습니다.
오늘은 세 개의 후크에 대해 적어보았는데요, 다음 포스팅에서도 이어서 적겠습니다.😄