팀 프로젝트 방콕스타일을 진행하면서 발생한 트러블 슈팅입니다.
발생한 오류 🔥
방콕 스타일 뉴스피드 프로젝트에서 게시물 목록을 렌더링 하던 중 페이지를 새로고침했을 때, `좋아요`가 랜덤으로 활성화된 상태로 표시되는 오류가 발생했습니다.
좋아요가 랜덤으로 표시되는 건 아주 큰 문제였기 때문에 해결이 시급했습니다.
해결 과정 🔎
useOnAuthStateChange
supabase에서 auth 관련 event가 발생할 때마다 알림을 받는 메서드입니다. 그래서 session이 있으면 컨텍스트에 `session.user`정보를 보내서 컨텍스트에서 유저 정보를 저장하게 됩니다.
// 유저정보를 context에 저장하는 함수
const useOnAuthStateChange = () => {
const { signIn } = useContext(EntireContext);
useEffect(() => {
const { data: authListener } = supabase.auth.onAuthStateChange((_, session) => {
session && signIn(session.user);
});
return () => {
authListener.subscription.unsubscribe();
};
}, []);
};
export default useOnAuthStateChange;
컨텍스트의 `userInfo`유저 정보가 있다면 유저 ID를 가져와 `getAllData`메서드에 전달하는 방식으로 로직을 짰습니다.
const { setDisplayedPosts, setAllPosts, userInfo } = useContext(EntireContext);
const [loading, setLoading] = useState(false);
// 유저 정보 확인
const userId = !!userInfo ? userInfo.id : null;
const fetchPosts = useCallback(async () => {
try {
setLoading(true);
const response = await getAllData(userId);
const data = formattedLikeData(response);
// 전체 게시글 데이터 저장
setAllPosts(data);
// 실제 화면에 보여줄 데이터 저장
setDisplayedPosts(filteredDisplayedPostsData(LIMIT_NUMBER, data));
} catch (error) {
console.error("게시글 데이터를 가져오지 못했습니다.", error);
} finally {
setLoading(false);
}
}, [userId]);
useEffect(() => {
fetchPosts();
}, [fetchPosts]);
근데 ` useOnAuthStateChange`비동기로 동작하기 때문에 로그인 여부에 따라 유저 정보를 컨텍스트에 업데이트하는 시간이 소요되는 문제가 있어서 `userInfo`가 설정되기 전에 `fetchPosts`함수가 먼저 실행 돼 `userInfo`가 null인 상태로 데이터를 가져오는 것이었습니다.
❗오류 가설
1. `useOnAuthStateChange` 훅의 비동기 동작으로 `userInfo`가 업데이트되기 전 `fetchPosts`함수가 호출됨.
이를 해결하기 위해 가장 먼저 시도한 방법은 `useCallback` 의존성 배열에 `userInfo`를 추가하는 것이었습니다.
const fetchPosts = useCallback(async () => {
if(!userInfo) return;
try{} catch(err){}
}, [userInfo]);
`userInfo`가 업데이트된 후에 다시 fetchPosts가 실행되어, 최신 사용자 정보를 바탕으로 데이터를 가져올 수 있을 것으로 기대했지만 여전히 동일한 문제가 발생했습니다. `userInfo`가 의존성 배열에 포함되었음에도 `useOnAuthStateChange`의 비동기 동작이 여전히 `fetchPosts` 호출 시점에 영향을 미치고 있다는 것이었습니다.
결국, `userInfo`가 `null`일 때도 좋아요 정보를 가져오도록 하는 방향으로 문제를 해결해야 된다고 판단했습니다.
해결 방법 ✨
`userInfo`가 `null`이더라도 좋아요 정보를 포함해 데이터를 가져오도록 쿼리를 수정했습니다.
const response = await supabase
.from("posts")
.select("*, likes(post_id)")
.order("created_at", { ascending: false });
로그인 여부와 상관없이 모든 게시글의 좋아요 상태를 가져올 수 있도록 하여 `userInfo`와 관계없이 올바르게 표시되었습니다. 결과적으로 페이지를 새로고침해도 좋아요 상태가 유지가 되었습니다.
깨달은 점❗
1. 비동기 로직의 복잡성
비동기 로직이 엮여있는 부분에서는 작은 타이밍 차이로 예기치 않는 오류가 발생할 수 있다는 것을 알게 되었습니다. 이런 오류를 해결하기 위해선 로직의 실행 순서를 정확하게 이해하고, 문제가 발생할 수 있는 경로를 미리 차단해야 한다고 생각했습니다.
2. 문제 해결 방법
문제를 해결할 때 하나의 방법에만 집착하기보다는, 다양한 접근 방식을 시도해 보는 것이 중요하다는 걸 알게 되었습니다. 이러한 과정에서 다양한 방법을 테스트해 보고, 그 결과를 분석하는 능력도 중요하다고 느꼈습니다.
회고 🧐
이 오류로 이틀을 날렸습니다,,, 이런 경험들이 앞으로 개발할 때 더 나은 판단을 할 수 있게 해 줄 것 같습니다.
아직 많이 부족합니다. 조언은 언제나 환영입니다~!
'공부 > 트러블 슈팅' 카테고리의 다른 글
[트러블 슈팅] Next.js generateStaticParams 정적 경로 생성의 오해와 해결 과정 (0) | 2024.10.07 |
---|---|
[트러블 슈팅] 카카오맵 API를 활용한 캠핑장 데이터 렌더링 최적화 (0) | 2024.09.19 |
[트러블 슈팅] SVG 컴포넌트 재사용 시 발생한 이미지 중복 문제 해결하기 (0) | 2024.09.15 |
[트러블 슈팅] MBTI 테스트 (Glitch에서 JSON-server의 응답 속도 차이) (1) | 2024.09.11 |
[트러블 슈팅] 방콕 스타일 (supabase RLS 오류) (0) | 2024.09.02 |
[트러블 슈팅] 포켓몬 도감 (svg, router, 이벤트 버블링) (0) | 2024.08.26 |
[트러블 슈팅] styled-components 오류 (표준, 비표준 속성) (2) | 2024.08.16 |
[트러블 슈팅] 커스텀 훅의 업데이트가 반영되지 않을 때 (0) | 2024.08.13 |