어제 Link를 사용하여 메인페이지갔다가 스크롤되는 useCallback 함수를 만들었는데
랜더링 오류가 너무 많이 일어나고 일일이 고칠수가 없었다...
할 수 없이 구글링을 하니깐 라이브러리가 있었고 설명도 잘되어있어서 적용하여 사용하기로 했다.
구글링을 먼저 해 볼것을 했다.
https://www.npmjs.com/package/react-router-hash-link
적용한 코드예시:
<Link to="/#mainSection" // 여기엔 루트경로와 #을쓰고 엘리먼트의 아이디값을 적는다.
scroll={() => {
clickHeaderButton("mainSection"); //여기엔 스크롤되어서 갈 함수를 콜백함수로 !!
}}
>
Home
</Link>
----------------React router hash link 라이브러리 사용전-----------------------
이제 이 작업을 마지막으로 마무리할 수 있을것 같다.
디테일 페이지의 헤더부분에서 Link를 통해 메인화면으로 갔다가 메인화면이 랜더링 되면 스크롤이동이
되는 페이지이다. 처음에는 그냥 순서대로 진행하면 될 것같아서
useEffect를 써주고 그 안에서 id의 값이 바뀌면 함수를 실행해주는 컴포넌트를 만들고
그 컴포넌트를 부모 컴포넌트로 만들고 {children} 이하에 오는 컴포넌트에 적용되게 해주었다.
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
const NavigationLink = ({ to, id, offset = 80, children }) => {
const navigate = useNavigate();
useEffect(() => {
if (id) {
const clickHeaderButton = (id, offset = 80) => {
const section = document.getElementById(id);
if (section) {
const sectionPosition = section.offsetTop;
window.scrollTo({
top: sectionPosition - offset,
behavior: "smooth",
});
}
};
clickHeaderButton(id, offset);
}
}, [id, offset]);
const handleClick = () => {
navigate(to);
};
return <span onClick={handleClick}>{children}</span>;
};
export default NavigationLink;
작동을 잘 되었다 !!! 성공인줄 알았지만 콘솔창을 보니
계속 하여 아래와 같은 에러가 발생하고 있었다.
Uncaught (in promise) Error: Extension context invalidated.
useEffect에 클린업을 하면 되지 않을까 싶어서 시도해보았다.
화면이 마운트 될 시에 값을 true로 해주고 언마운트 될때 false로 해주면
랜더링이 끝나고 화면이 언마운트 되면서 useEffect 내의 이벤트리스너 함수 실행이 종료된다.
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
const NavigationLink = ({ to, id, offset = 80, children }) => {
const navigate = useNavigate();
useEffect(() => {
let isMounted = true;
if (isMounted && id) {
const clickHeaderButton = (id, offset = 80) => {
const section = document.getElementById(id);
if (section) {
const sectionPosition = section.offsetTop;
window.scrollTo({
top: sectionPosition - offset,
behavior: "smooth",
});
}
};
clickHeaderButton(id, offset);
}
return () => {
isMounted = false;
};
}, [id, offset]);
const handleClick = () => {
navigate(to);
};
return <span onClick={handleClick}>{children}</span>;
};
export default NavigationLink;