Intersection Observer API - Web API | MDN
Intersection Observer API는 타겟 요소와 상위 요소 또는 최상위 document 의 viewport 사이의 intersection 내의 변화를 비동기적으로 관찰하는 방법입니다.
developer.mozilla.org
한번에 이해하면 천재! 옵저버 공식문서 👆
let options = {
root: document.querySelector('#scrollArea'),
rootMargin: '0px',
threshold: 1.0
}
let observer = new IntersectionObserver(callback, options);
observer API 는 매우 유용한 API 이다.
뷰포트와 관찰자를 설정해 그 둘이 만나는 지점의 true/false 값을 이용해 인터렉티브한 요소들을 마구 그려낼 수 있다.
공식 문서에서는 option의 threshold 에 퍼센트 배열을 넣고 가시성 비율
entry.intersectionRatio
을 사용해 박스가 보여지는 범위마다 색깔을 다르게 나타내는 UI 를 예시로 보여주었는데
catbow 라이브러리도 요런 원리로 돌아간다
이렇게보니 그 동안 무한 스크롤을 구현한 건 정말 observer API 의 10%만 써왔던 게 아닐까 싶다
다시 옵저버를 공부하고자 무한스크롤을 간단하게 다시 구현해보았는데

무한 스크롤을 거꾸로 만들었다 ㅋㅋㅋㅋㅋㅋ
flex-direction : column-reverse 로 데이터가 반대로 쌓이게 만들었다
다만 클린업 부분들 좀 다르게 주었는데 (https://kimjunho97.tistory.com/3 참고)
useEffect 인자성 빈 배열 안에 observer를 넣어 한번만 일어나게 했다.
observer 자체를 한번만 일으키니 굳이 클린업 작업이 필요 없다
그리고 만났던 다른 오류로는
전체 페이지를 viewPort로 잡지 않고 컴포넌트에 달기 위해 뷰포트를 따로 만들어주었는데
이 때문에 어디든지 관찰자가 잡혀 무한으로 스크롤되는... 오류를 만났다
이는 관찰자 크기를 10vw, rootMargin을 10px 늘려 오류를 고쳤다.
const Observer = () => {
const [data, setData] = useState([]);
const refObserver = useRef(null);
const viewport = useRef(null);
useEffect(() => {
const options = {
root: viewport.current,
rootMargin: "0px 0px 10px 0px",
threshold: 0.5,
};
const handleObserver = () => {
axios.get("./data.json").then((res) => setData((pre) => [...pre, ...res.data]));
};
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
handleObserver();
}
});
}, options);
}, []);
// eslint-disable-next-line react-hooks/exhaustive-deps
console.log("data", data);
return (
<>
<div
ref={viewport}
style={{
padding: "5px",
border: "1px solid black",
overflow: "scroll",
height: "100vh",
display: "flex",
flexDirection: "column-reverse",
}}
>
<Layout>
{data?.map((el, id) => {
return <Container key={id} el={el} idx={id} />;
})}
<div style={{ background: "blue", width: "10vw", height: "1px" }} ref={refObserver} />
</Layout>
</div>
</>
);
};
export default Observer;
나중에 옵저버로 채팅창도 만들어 보고 싶다 ☺️
'TIL' 카테고리의 다른 글
[Context] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment> (0) | 2023.01.21 |
---|---|
React 깔끔하게 컴포넌트 import 하기 (0) | 2023.01.19 |
프로그래머스 js 마법의 엘리베이터 (0) | 2022.12.31 |
바벨 (0) | 2022.12.27 |
자바스크립트 Dom 이란? (0) | 2022.12.27 |
댓글