useEffect(() => {
console.log("컴포넌트가 마운트될 때 실행됨!");
return () => { // clean-up 함수
console.log("컴포넌트가 언마운트도리 때 실행됨!");
};
}, []); // 빈 배열이면 처음 마운트될 때 한번만 실행
요약: useEffect는 특정 상황에서 어떤 동작을 실행할 때 사용됨
const handleClick = useCallback(() => {
console.log("버튼 클릭");
}, []); // 의존성이 없으므로 최초 랜더링 시 한번만 생성됨
요약: useCallback은 같은 함수를 재사용하고 싶을때 사용됨
searchParams에 의해 첫번째 useEffect 실행 → searchParams에 의해 fetchSearchResult 재정의
→ fetchSearchResult에 의해 onInterSection 재정의 → 최초로 onInterSectionObserver 실행 → onInterSection이 재정의 되었으므로 onInterSectionObserver 실행
useEffect(() => {
console.log("useEffect 초기화 실행");
setPlaces([]);
setHasMore(true);
setPage(0);
// setIsLoading(false);
}, [searchParams]);
const fetchSearchResult =
useCallback(
async (pageNum) => {
// 로딩 true 이거나 hasMore false이면 리턴
console.log("fetchSearchResult 실행");
// if (isLoading || !hasMore) return;
// setIsLoading(true);
try {
const params = {
...Object.fromEntries(searchParams.entries()),
page: pageNum,
size: 10,
};
console.log("params = ", params);
const response = await getSearchPlaces(params);
console.log("response = ", response);
const { content, sliceInfo } = response.data.data;
setPlaces((prev) => [...prev, ...content]);
if (sliceInfo.last) {
setHasMore(false);
} else {
setPage((prev) => prev + 1);
}
} catch (error) {
console.log("검색 결과 오류 = ", error);
}
// finally {
// setIsLoading(false);
// }
}
,
// [searchParams, isLoading, hasMore]
[searchParams]
);
const onIntersection = useCallback(
(entries) => {
const firstEntity = entries[0];
if (firstEntity.isIntersecting && hasMore) {
console.log("onInterSection 실행");
fetchSearchResult(page);
}
},
// [hasMore, page, fetchSearchResult]
[hasMore, page]
);
useEffect(() => {
console.log("onInterSectionObserver 초기화 실행");
const observer = new IntersectionObserver(onIntersection, { threshold: 1 });
const currentRef = loadMoreRef.current;
if (currentRef) {
observer.observe(currentRef);
}
return () => {
if (currentRef) {
observer.unobserve(currentRef);
}
};
}, [onIntersection]);