2020. 8. 23. 01:44ㆍProject
디테일 페이지 라우팅을 하며 겪은 문제
프로젝트 상세 페이지는 params로 id값을 받고, 그 id값에 따라서 임시 데이터에서 정보를 가져온 뒤, 화면을 렌더링하는 형태이다.
하지만 프로젝트 상세 페이지에서 새로고침을 하면 아래와 같은 문제가 발생한다.
구글링을 통해서 아래와 같은 해결 방법을 발견했다.
https://ui.dev/react-router-cannot-get-url-refresh/
브라우저가 모든 라우팅 로직을 처리하기 위해서 클라이언트 측의 라우팅인 React-Router에만 의존하고 있기 때문에, 새로고침을 했을 때 프로젝트 상세 페이지인 /project/2 이라는 서버의 라우팅이 존재하지 않는다. 그래서 cannot/GET 오류가 나온다.
보통 webpack-dev-server을 사용하는 경우에 webpack-dev-server에게 모든 request를 index.html로 리다이렉션 시켜주는 것이 필요하다.
그래서 webpack.config.js 파일을 아래와 같이 설정해주었다.
module.exports = {
(...)
output: {
path: path.join(__dirname, "/dist"),
filename: "main.js",
publicPath: "/", /* 추가 */
},
/* 아래 부분 추가 */
devServer: {
historyApiFallback: true,
},
(...)
};
커스텀 Hook 만들기
네비게이션 바에 스크롤에 따라서 애니메이션을 주고 싶었다.
그래서 스크롤 이벤트를 다는 것을 찾아보다가, 커스텀 Hook을 만들기로 했다.
일정 범위 내에서 스크롤을 하면, 상단 고정 네비게이션 바의 opacity에 변화를 주고 싶었다.
노마드코더의 react hooks 강의가 custom hooks를 만드는 과정을 보여주고 있어서, 그 중 useScroll을 참고해서 만들기로 했다.
import React, { useEffect, useState } from "react";
const useScroll = () => {
const [pageY, setPageY] = useState(0);
const onScroll = (e) => {
console.log(window.pageYOffset);
};
useEffect(() => {
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
return state;
};
export default useScroll;
위의 코드처럼 현재 스크롤중인 Y축 위치를 가져오기 위해서 스크롤 이벤트를 달아 주었다.
특정 구간에서만 스크롤 이벤트가 일어나도록 할 생각이라, 계속 그 구간을 찾기 위해서 스크롤링 할때마다 이벤트 트리거가 걸리고 있었다.
이벤트를 일정 간격을 두고서 실행될 수 있도록 해주고 싶어서, Debounce & Throttle 을 적용시키기로 했다.
Debounce & Throttle
- Debounce:
이벤트를 그룹화해서 특정 시간이 지났을 때 하나의 이벤트만 실행되도록 해준다. - Throttle:
마지막 이벤트가 호출된 후 일정 시간이 지날 때까지 해당 이벤트가 호출되지 못하도록 하는 것으로, 실행 횟수에 제한을 건다.
스크롤 이벤트에는 Throttle을 적용시키는 것이 더 나을 것이라고 판단했다.
import React, { useEffect, useState, useCallback } from "react";
import { throttle } from "lodash";
const useScroll = () => {
const [pageY, setPageY] = useState(0.7);
const onScroll = throttle((e) => {
const scrollTop = window.scrollY;
const docHeight = document.body.offsetHeight;
const winHeight = window.innerHeight;
const scrollPercent = scrollTop / (docHeight - winHeight) + 0.7;
setPageY(scrollPercent >= 1 ? 1 : scrollPercent);
}, 50);
useEffect(
useCallback(() => {
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []),
[]
);
return pageY;
};
export default useScroll;
시간 관계상 lodash 라이브러리의 Throttle을 가져다가 썼다.
나중에 직접 구현해 보고 싶다.
'Project' 카테고리의 다른 글
[Personal Portfolio] 3. 라우팅 및 네비게이션 섹션 이동하기 (0) | 2020.08.20 |
---|---|
[Personal Portfolio] 2. 리액트 앱에서 ESLint 설정하기 (0) | 2020.08.18 |
[Personal Portfolio] 1. CRA 없이 리액트 앱 시작하기 (0) | 2020.08.17 |
[Final Project] 4주 프로젝트 회고 (0) | 2020.08.13 |
[First Project] 2주 프로젝트 회고 (0) | 2020.07.12 |