이슈
- 모니터링 도구에서
Error: Abort fetching component for route: "/dashboard"
에러가 발생되는 것이 추적되었습니다
- router를 통해 경로를 동시에 변경하는 경우에 발생되는 것이 원인이었습니다
해결
- 참고에 있는 스택오버플로우의 답변을 참고하여 약간 수정 후 해결하였습니다
import { useRouter } from 'next/router';
import { useCallback, useEffect, useRef } from 'react';
const useSafeRouter = () => {
const onChangingRef = useRef(false);
const handleRouteChange = () => {
onChangingRef.current = false;
};
const router = useRouter();
const safePush = useCallback(
(path: string) => {
if (onChangingRef.current) {
return;
}
onChangingRef.current = true;
router.push(path, undefined, { shallow: true });
},
[router],
);
const safeReplace = useCallback(
(path: string) => {
if (onChangingRef.current) {
return;
}
onChangingRef.current = true;
router.replace(path, undefined, { shallow: true });
},
[router],
);
useEffect(() => {
router.events.on('routeChangeComplete', handleRouteChange);
return () => {
router.events.off('routeChangeComplete', handleRouteChange);
};
}, [router]);
return { router, safePush, safeReplace };
};
export default useSafeRouter;
- router가 변경 중인지 확인하는 플래그(onChangingRef)를 만듭니다
- 경로가 변경 직전에
onChangingRef.current = true;
로 만들어서 변경 중 이라는 것을 알리고
- router가 경로 변경이 완료되면 내부에서 실행되는 routeChangeComplete 이벤트에서
onChangingRef.current = false;
로 만듭니다
- 만약 router가 변경 중이라면 중복해서 변경이 되지 않게 하는 로직입니다
if (onChangingRef.current) { return; }
useState vs. useRef
- React에서 전역 변수를 만드는 방법은 두 가지가 있습니다
- 차이점
- useState는 렌더링에 영향을 주고 useRef는 렌더링에 영향을 주지 않습니다
- 또한 useState의 값을 변경하는 setter함수는 비동기적으로 값이 변경되지만 useRef는 즉시 동기적으로 변경됩니다
- stack overflow의 답변에는 useState를 사용했지만 에러가 해결되지 않아 useRef로 변경하여 해결하였습니다
참고