https://simian114.gitbook.io/blog/undefined/react/intersectionobserverapi
위 게시물의 내용을 보고 이해한 내용을 담았다.
필요한 개념:
- useState로 반환된 setter 함수랑 useref랑 연동해서 쓰는 법
- 리액트 state를 스냅샷으로 관리하는 개념, 이를 통해서 useEffect에서 언마운트 될 때 observe 대상 변경하는 것
import { useEffect, useRef, useState } from 'react';
import 'intersection-observer';
export const useIntersectionObserver = (callback) => {
const [observationTarget, setObservationTarget] = useState(null);
const observer = useRef(
new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (!entry.isIntersecting) return;
callback();
})},
{ threshold: 1 }
)
);
useEffect(() => {
const currentObserver = observer.current;
if (observationTarget) {
currentObserver.observe(observationTarget);
}
return () => {
if (observationTarget) {
currentObserver.unobserve(observationTarget);
}
};
}, [observationTarget]);
return setObservationTarget;
};
커스텀 훅을 만드는 코드이다.
- useState를 통해 observationTarget과 setObservationTarget을 생성한다.
- observer는 리랜더링에도 새로 생성되지 않도록, 성능향상을 위해 useRef로 만들어준다. 교차하고 있다면 콜백함수를 실행시켜준다.
- observationTarget이 변경될 때마다 useEffect를 통해 새로운 타겟을 구독한다.
- useEffect가 언마운트 될 때, 기존의 구독을 풀어준다.
사용은 이런식으로 한다.
const setObservationTarget = useIntersectionObserver(fetchMoreComments);
function CardList() {
...
return (
<StyledCardListContainer>
{comments.map((comment) => (
<Card key={comment.id} comment={comment} />
))}
{isLoading && <div>Loading...</div>}
{!isLoading && <div ref={setObservationTarget}></div>}
</StyledCardListContainer>
);
- setObservationTarget이 리턴되었다.
- ref에 set함수를 넣어준다, observationTarget은 해당 ref를 참조한다.
- 해당 div에 해당하는 값이 setObservationTarget()안에 들어가서 훅이 실행된다.
- ObsercationTarget의 값이 변하므로, useEffect도 실행된다.
- currentTarget에 해당 div가 들어오면서,observer가 observe 할 수 있다.
'프론트엔드' 카테고리의 다른 글
클로저, 렉시컬 환경 관점에서 본 useEffect 클린업 함수 (0) | 2023.08.01 |
---|---|
intersection observer의 entries 진짜 마지막으로 이해하기 (0) | 2023.07.31 |
intersection observer 이해하기 (0) | 2023.07.30 |
프론트에서 DFS로 무한 대댓글 구현하기 (0) | 2023.07.28 |
프로젝트 배포할 때는 환경변수 설정을 어떻게 할까? (0) | 2023.07.25 |