
💡노마드코더 수강이후 개인작업을 하며 직면한 문제의 해결과정을 기록한 포스트입니다.
목표1을 위해서 useRef와 scrollIntoView사용.
목표2를 위해서 prop(emit)을 사용했다.
useRef
특정 DOM을 선택해서 조작할 수 있도록 해주는 React의 Hook.
💫React공식문서 : useRef
친절하게도 내가 원하는 기능이 리액트 공식문서에 기재가 되어있었다.
이것을 응용하여 원하는 기능을 구현하기로 했다.
component IndexHeader의 Nav의 값들을 부모요소인 PageIndex에 전달을 해야했다.
Nav를 propsNavId라는 이름으로 PageIndex에 전달하겠다고 선언했다.
function IndexHeader({ propHeader, propsNavId }) {...}
Nav를 클릭할 때 이벤트를 실행하기 위해 handleSelect를 걸어주었다.
<Tab.Content
className={Style.tabWrap}
onClick={handleSelect}
>
.
//총 4개의 nav가 만들어졌고, 각각의 nav에는 id로 indexNum(0~3)을 넣어줬다.
<nav
id="index"
>
.
</Tab.Content>
handleSelect가 실행되면, propsNavId의 값으로 nav의 id가 들어간다.
function handleSelect(e) {
propsNavId(e.target.id);
}
import { useRef } from 'react';
리액트 Hook인 useRef를 먼저 import했다.
그리고 스크롤이벤트가 적용될 섹션들을 담을 listRef를 선언했다.
const listRef = useRef(null);
섹션을 감싸는 부모요소에 ref값을 주었다.
자식요소인 IndexHeader에서 보내주는 propsNavId을 받고, 그 값을 index로 응용할 함수를 선언해주었다.

function SelectNavi(data) {
const listNode = listRef.current;
const imgNode =
listNode.querySelectorAll('section')[data];
imgNode.scrollIntoView({
behavior: 'smooth',
});
}
여기까지 진행하면 nav를 클릭 했을 때 해당 섹션으로 부드럽게 이동을 하지만 스크롤을 했을 때 화면에 보여지는 section에 해당하는 nav는 하이라이트 처리가 되지 않는다.
스크롤에 따라서 nav에 하이라이트가 되도록 이벤트를 더 걸어주기로 했다.
디폴트 값이 false인 스크롤값을 담는 useState 선언.
const [isScroll, setScroll] = useState(false);
내가 만든 header의 높이가 80px이므로 스크롤값이 80px이상이면 isScroll은 true, 80px미만이면 false가 되도록 함수를 만들었다.
useEffect(
() =>
window.addEventListener('scroll', () => {
if (window.scrollY > 80) {
setScroll(true);
} else {
setScroll(false);
}
}),
[]
);
추가로 PageIndex의 section들의 scrollY를 측정을 하고 그 값에 따라서 setTabs의 state가 바뀌도록 했다. 해당 이벤트는 scroll이 될 때 마다 실행되므로 의존값인 isScroll을 넣어주었다.
useEffect(
() =>
window.addEventListener('scroll', () => {
if (window.scrollY > 80) {
setScroll(true);
if (window.scrollY < 920) {
setTabs('introduce');
} else if (
window.scrollY >= 920 &&
window.scrollY < 1760
) {
setTabs('product');
} else if (window.scrollY >= 1760) {
setTabs('this page');
}
} else {
setScroll(false);
setTabs('hello');
}
}),
[isScroll]
);
