1. 좋아요 버튼: 하트 10번 계속 클릭하기 (Optimistic Update 사용)
* Priority : Normal ➡️ Immediate
* Commited at : 0.5 s ➡️ 1.8 s
* Render : 38.5 ms ➡️17.4 ms
* Layout effects : 8.2 ms ➡️ 0.2 ms
* Passive effects : 2 ms ➡️ 0.6 ms
2. 카테고리 - 습관 인증
* Render : 41.8 ms ➡️26.8 ms
* Layout effects : 6 ms ➡️ 3.7 ms
* Passive effects : 2.2 ms ➡️ 1.7 ms
3. 카테고리 - 전체보기
* Render : 45.7 ms ➡️ 29.9 ms
* Layout effects : 4.8 ms ➡️ 3.7 ms
* Passive effects : 2.7 ms ➡️ 1.8 ms
[변경 사항]
1. useInfiniteQuery 조회 형태 변경
(1) 목적 : 더 보기 기능으로 데이터 가져올때 부하 줄이기
(2) 변경 필요 : 좋아요 기능을 optimistic update를 하기 위해서는 구조 변경 필요
(3) 변경 전
: queryFn : querySnapshot.docs 리턴
=> 좋아요 기능 queryClient.setQueryData <InfiniteData<PostType[]>>으로 가져오는 oldData 형태 문제
=> oldData : QueryDocumentSnapshot 구조
=> getData: pages.flat()하여 map으로 doc.data()를 하여 데이터를 가공
=> updateData : 원하는 데이터 (좋아요 버튼: isLiked 값 변경)
=> return : updateData를 대입하려고 했으나, 다시 QueryDocumentSnapshot 구조로 변경해야할 것 같음
=> 현재 사용되는 oldData의 구조를 변경하기 위해서는 useInfiniteQuery 구조를 변경해야함!
(oldData : QueryDocumentSnapshot 구조 x / 데이터 형식의 객체 o)
(▼Optimistic Update 구현하려고 시도했으나 안 되던 코드 ▼ )
queryClient.setQueryData<InfiniteData<PostType[]>>
([QUERY_KEYS.POSTS, category], (oldData) => {
let getData = oldData?.pages.flat().map((doc) => {
const postData = doc.data();
return {
id: doc.id,
isLiked: postData.likedUsers?.includes(auth.currentUser?.uid || ''),
...postData
};
});
const updateData = getData?.map((post) => {
if (post.id === selectedPostId) {
return {
...post,
isLiked: !post.isLiked
};
} else {
return post;
}
});
return {
pages: oldData?.pages ?? [],
pageParams: oldData?.pageParams ?? []
};
});
(4) 변경 후
: queryFn : querySnapshot.docs ➡️ posts.push({ id: doc.id, ...postData, isLiked: isLiked, snapshot: doc }); 리턴
=> oldData : 데이터 형식의 객체로 가져오기
=> 특이한 점은, map을 2번 사용해야한다
useInfiniteQuery는 2가지의 배열로 구성된 객체|
(1) pages 배열 ( 각 페이지에 대한 데이터 갖고 있음 )
(2) pageParams 배열 ( 각 페이지를 불러올 때 사용된 매개변수를 갖고있음 )
queryClient.setQueryData<InfiniteData<PostTypeFirebase[]>>([QUERY_KEYS.POSTS, category], (oldData) => {
if (!oldData) return oldData;
const updateData = oldData?.pages.map((pagesPost) => {
return pagesPost.map((post) => {
const newLikeCount = post.isLiked ? post.likeCount - 1 : post.likeCount + 1;
if (post.id === selectedPostId) {
return {
...post,
isLiked: !post.isLiked,
likeCount: newLikeCount
};
} else {
return post;
}
});
});
return {
...oldData,
pages: updateData
};
});
=> 원래의 'oldData'객체를 스프레드 연산자를 사용해서 복사하고
이 복사된 객체의 'pages'속성을 'updateData' (좋아요 숫자 , 좋아요 여부)로 적용해서
새로운 InfiniteData 객체 반환.
[체크 사항]
조회 & 좋아요 기능에 맞게 변경했기에, 기존에 잘 동작하던 부분도 같이 테스트하기
➡️ prefetch 한 부분
➡️ 새 글 작성 후 카테고리 이동시 오류 발생 (썸네일 undefined 오류)
➡️ 디테일 페이지에서 댓글 작성 후 커뮤니티 페이지에 반영 안 됨 (queryKey의 invalidateQueries 변경)
끝.
'TIL :: Today I Learned' 카테고리의 다른 글
리액트 최적화 (3) 폰트 : FOIT | FOUT | Subsets | Preload (0) | 2024.03.01 |
---|---|
리액트(CRA) 최적화(2) Lazy-Loading | Preload | CLS 제거 (2) | 2024.03.01 |
리액트 최적화(1) 이미지 : Format + cloudinary (0) | 2024.02.13 |
useEffect의 dependency array에서 무한루프 (0) | 2024.02.06 |
데이터 수정/삭제시 쿼리키 invalidateQueries (0) | 2024.01.31 |