일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 공연티켓
- nft
- polygon
- Ai
- Laravel
- nodejs
- node
- Python
- exceljs
- 오블완
- miniconda
- 라라벨
- PM2
- CSS
- nginx
- Kaikas
- pagination
- React
- jquery
- 티스토리챌린지
- Setting
- chatGPT
- threejs
- 배포
- netfunnel
- Remix
- 블록체인
- metamask
- 회고
- NextJS
- Today
- Total
박주니 개발 정리
observe 적용 방법 본문
우선 observe 적용에 대해서 설명하기 전에 observe를 사용했던 이유는 무한 스크롤 최적화를 하기 위함입니다. 특정 요소를 지나갈 때마다 새로운 컨텐츠를 로드할 수 있습니다. 그 외 이미지나 동영상 등의 미디어 로딩, 광고 배너 등의 노출, 애니메이션 실행, 로딩바등 최적화할 때 사용합니다.
조건) 기본적인 리스트 데이터 api 연결해주시길 바랍니다.
1. new IntersectionObserver을 이용해서 기본 구성을 만들어주시길 바랍니다.
import {useRef} from "react";
const obsRef = useRef(null); //observer Element
useEffect(() => {
//옵저버 생성
const observer = new IntersectionObserver(obsHandler, { threshold: 0.5 });
// IntersectionObserver 상호작용
if (obsRef.current) observer.observe(obsRef.current);
return () => {
// 인스턴스 해제
observer.disconnect();
};
}, []);
return (
<>
<ul>
// list 나오는 부분
</ul>
<div ref={obsRef}></div>
</>
)
- <div ref={obsRef}></div>: react의 가상 돔과 별개로 dom 엘리먼트에 직접 접근할 수 있어서 불필요한 렌더링을 방지할 수 있습니다.
- if(obsRef.current) observer.observe(obsRef.current): obsRef.current를 console로 확인해보면 div가 나오는 것을 확인하실 수 있습니다. 스크롤 진행시 div영역 전까지 observer.observe()는 IntersectionObserver 상호작용한다는 의미입니다. (해당 영역에서는 스크롤할 때 데이터를 불러옵니다)
- observer.disconnect(): observer 영역에 벗어나는 경우 observer.disconnect()로 observer 인스턴스 해제합니다.
2. 무한 스크롤 페이지 갯수 변수를 설정하고 new IntersectionObserver에 들어갈 obsHandler을 설정합니다. 그리고 가져올 데이터 함수에 page 매개변수를 전달합니다.
let p2 = 1; // 무한스크롤 page 갯수
const [page, setPage] = useState(1);
useEffect(() => {
getList(page)
}, [])
//무한스크롤때문에 추가
const obsHandler = (entries) => {
//옵저버 콜백함수
const target = entries[0];
console.log("target", target);
if (target.isIntersecting) {
//옵저버 중복 실행 방지
p2 = p2 + 1;
setPage(p2);
}
};
설명) 스크롤 진행시 데이터가 존재할 경우 페이지가 계속 +1씩 진행될 수 있게 만듭니다. obsHandler 함수가 observe에 core 부분이 될 수 있습니다.
3. getList 함수에 페이지갯수를 받았을 때 전체 데이터갯수와 비교해서 preventRef를 설정합니다.
추가 설명) 2번에서 getList(page) 전달받은 매개변수가 _page 입니다.
const cnt = 3; // 한 페이지당 갯수
const preventRef = useRef(true); //옵저버 중복 실행 방지
const [isLast, setIsLast] = useState(false); // Load More 표시
const getNftList = async (_page) => {
setLoad(true); //로딩 시작 //무한스크롤때문에 추가
const p = _page ? _page : page;
axios(`${process.env.NEXT_PUBLIC_API_URL}/api/main`, {
....
})
.then((res) => {
const data_ast = data.assets; // 데이터 리스트
let list;
list = data_ast.slice(0, cnt * p); // 한페이지에 나올 데이터
setTList([...list]);// 한페이지에 나올 데이터 셋팅
/*데이터 전체 갯수와 현재 페이지 갯수 비교*/
if (list.length == data.assets.length) {
setIsLast(true);
preventRef.current = false;
} else {
preventRef.current = true;
setIsLast(false);
}
setLoad(false); //로딩 종료 //무한스크롤때문에 추가
})
.catch((error) => {
console.log(error)
});
};
- cnt 설명) cnt를 3으로 설정했을 때 스크롤 진행시 3개 나오고 밑에 obsRef를 인식을 하고 다른 데이터 3개를 부르게 됩니다. 즉 1페이지에 3개씩 나온다고 이해하시면 됩니다.
4. obsHandler 함수에서 preventRef를 추가해서 true일경우에만 조건이 성립하게 만듭니다.
//무한스크롤때문에 추가
const obsHandler = (entries) => {
//옵저버 콜백함수
const target = entries[0];
if (target.isIntersecting && preventRef.current) {
preventRef.current = false;
if (!isLast) {
p2 = p2 + 1;
setPage(p2);
getNftList(p2);
}
}
};
tip) 먼저 만들때 observe를 이용한 리스트를 만들기보다는 전체 리스트를 만들고나서 observe를 셋팅하시는 것을 추천합니다. 그리고나서 적용 순서를
1. setPage와 setIsLast를 설정
2. cnt 한페이지 갯수 설정
3. return 안에 데이터리스트 하단에 <div ref={obsRef}></div> 설정
4. new IntersectionObserver 및 obsHandler 셋팅
5. 정상작동 되는 지 확인
6. 현재 페이지와 전체 데이터 페이지 비교해서 preventRef 조건 셋팅
7. obsHandler 조건 추가
이 방식으로 진행하시면 이해하시기 편하실거라 생각합니다.