따봉프로젝트 트러블 슈팅

·2022년 6월 30일
0

트러블슈팅 기록

목록 보기
1/3

개요

프로젝트중 매인피드의 스크롤 관련 훅에서 문제가 발생했다.

해당 코드는 useScroll이라는 커스텀 훅이다

export const useScroll = () => {
const [offset, setOffset] = useRafState({ x: 0, y: 0 });
const ref = useRef(null);

useEffect(() => {

	const element = ref.current;
	if (!element) return null;
	const handleScroll = () => {
		setOffset({
			x: ref.current.scrollLeft,
			y: ref.current.scrollTop,
		});
	};

	element.addEventListener('scroll', handleScroll, { passive: true });

	return () => element.removeEventListener('scroll', handleScroll);
	}, [ref, setOffset]);
	return [ref, offset];

};

해당 코드는 mainFeed Page에서 발췌했다.

const [firstLoading, setFirstLoading] = useState(true);

const [ref, isScrollDown] = useScrollDown();
{firstLoading ? (
<Spinner />
) : (
	<S.MainFeedPageContainer
	ref={ref}
	className={!isScrollDown ? 'bannerShown' : null}
>

mainFeed 페이지에서 useScroll훅을 내부에서 사용하는 useScrollDown 훅을 사용한다.

현재 mainFeed 페이지에서는 firstLoading 상태값에 따라서, MainFeedPageContainer 컴포넌트가 렌더링이 되는데

firstLoading === true 일때에는 해당 컴포넌트는 렌더링이 되지 않는다.

첫번째 문제는 useEffect에서 문제가 발생했다,

문제가 뭔지 보니

Warning: useEffect must not return anything besides a function, which is used for clean-up. You returned null. If your effect does not require clean up, return undefined (or nothing).

에러이다 .

해서 if (!element) return null 해당 코드에서 return null 이 아닌 retrun 으로 수정을 하니 해결이 되었다.

useEffect return에는 null을 사용해서는 안된다고 한다.

왜 일까?

두번째 문제는, 리렌더링시 Ref가 예전 dom을 가르킨다는 것

mainFeedPage가 리렌더링이 되고 난후에는
useScroll useEffect 내부에서는 Ref로 할당한 dom을 가져오지 못하는 문제가 있었다.

해당문제는 mainFeedPage에서는 useScrollDown으로 받아온 Ref를 할당한 dom이 확인 가능하지만
useScroll 내부에서는 확인이 안되었다. 즉 useEffect가 재실행이 안되고 있었다.

useEffect deps에는 [ref, setOffset] 를 할당을 했는데 왜 안되는건지 고민한결과.
ref은 객체로 들오온다
ref안에는 current가 있다 즉 current가 변경이 되었을때 useEffect가 실행되게 바꾸면 어떻게 될까?

[ref.current, setOffset] 로 변경하니 실행이 됐다.

왜일까

useEffect 의 dependency array에 object를 넣으면 object의 reference가 변경될 때 마다 실행된다.

해서 ref의 객체 참조가 변경이 안되고 current값만 변경이 되었기 때문에 이런 현상이 발생했다.

0개의 댓글