
const CoverflowSection = () => {
const captionDatas = useCaptionDatas();
const { coverflowSectionRef, captionsRef } = useCoverflowRefs();
useDisplayCaptions({ captionsRef });
useCoverflowScroll({ coverflowSectionRef, captionsRef });
return (
<CoverflowSectionWrapper ref={coverflowSectionRef}>
{captionDatas?.map((caption, i) => (
<CoverflowCaption
key={caption.id}
ref={(captionElem: HTMLDivElement) => {
captionsRef.current[i] = captionElem;
}}
data={caption}
onClick={() => handleCaptionClick(i, { coverflowSectionRef, captionsRef })}
index={i}
/>
))}
<Placehorder />
</CoverflowSectionWrapper>
);
};
export default CoverflowSection;
useDisplayCaptions 훅에 captionDatas 업데이트가 감지되지 않아 렌더링 초기 1회만 display 되고 captionDatas가 업데이트 되는 경우는 고려되지 않음
const useDisplayCaptions = ({ captionsRef }: useDisplayCaptionsProps) => {
useEffect(() => {
displayCaptions({ captionsRef, selectedIndex: 0, scrollLeft: 0 });
}, [captionsRef]);
};
export default useDisplayCaptions;
해결책: captionDatas를 prop으로 전달해 useEffect에 의존성 추가
const useDisplayCaptions = ({ captionsRef, captionDatas }: useDisplayCaptionsProps) => {
useEffect(() => {
displayCaptions({ captionsRef, selectedIndex: 0, scrollLeft: 0 });
}, [captionsRef, captionDatas]);
};
export default useDisplayCaptions;
왜 이런 문제가 발생했을까? supabase 도입 전에는 mockdata를 활용해 api 통신이 필요 없었기에 초기 1회만 랜더링 해주면 동작했지만 아래 코드와 같이 captionDatas의 초기 값은 null이므로 useDisplayCaptions 내 useEffect에 의존성 주입이 필요해짐
const useCaptionDatas = () => {
const [captionDatas, setCaptionDatas] = useState<CaptionData[] | null>();
useEffect(() => {
const fetchCaptions = async () => {
const { data, error } = await supabase.from('captionDatas').select('*');
console.log(data);
setCaptionDatas(data);
if (error) {
console.log(error);
}
};
fetchCaptions();
}, []);
return captionDatas;
};
export default useCaptionDatas;
최종 결과
