구현할 기능
게시물 갯수, 팔로워 수, 댓글 수 별 유저 랭킹 기능
구현 이유
50명의 유저에게 피드백 받은 후 게시물 게시 유도를 위한 추가기능 구현
참고 회의 내용 : https://www.notion.so/e7ae5984cf72445a8f9dff0042e7480c?v=035c9f9341a243668c11c1f213969cb5&pvs=4
기능 구현
reactQuery를 활용하여 데이터를 요청한다.
여기서 게시물, 팔로워, 댓글에 따라 각기 다른 요청방법을 사용한다.
- 전체 데이터를 불러온 후 현재 로그인 된 유저 기준 랭킹 번호를 알아낸다
- 필요한 데이터를 filter와 map을 통해 구한다
- slice를 통해 유저 기준 앞,뒤 유저 데이터를 구한다
게시물 랭킹
const { data: rankPost } = useQuery(['rankPost'], getData, {
staleTime: 1000 * 60 * 10,
cacheTime: 1000 * 60 * 15,
});
// 모든 유저 데이터 가져오기
const { data: rankUser } = useQuery(['rankUser'], getUser, {
staleTime: 1000 * 60 * 10,
cacheTime: 1000 * 60 * 15,
});
// 유저 목록 추출
const users: string[] = Array.from(
new Set(rankPost?.map((post: RankPost) => post.creator))
);
// 유저별 포스트 추출
let userPosts: RankUserPost[] = users.reduce<RankUserPost[]>((acc, user) => {
acc.push({
user,
posts: rankPost.filter((post: RankPost) => post.creator === user),
});
return acc;
}, []);
// 유저별 포스트 정렬
userPosts.sort(function (a, b) {
if (a.posts.length < b.posts.length) {
return 1;
}
if (a.posts.length > b.posts.length) {
return -1;
}
return 0;
});
//해당 유저의 랭킹
const myRankNum = userPosts?.map((item: any, index: any) => {
if (item.user === authService.currentUser?.uid) return index;
});
const myRanking: any = myRankNum?.filter((item: any) => item > -1);
const myRank = userPosts?.filter((item: any) => {
if (item.user === authService.currentUser?.uid) {
return item;
}
});
// 해당 유저 기준 앞 뒤 랭킹 데이터
const preRank = userPosts?.slice(myRanking - 1, myRanking);
const nextRank = userPosts?.slice(myRanking, myRanking + 1);
const nextRankNum = nextRank?.filter((item: any, index: any) => index === 1);
팔로워 랭킹
// 팔로워 데이터 불러오기
const { data: rankFollower } = useQuery(['rankFollwer'], getFollow, {
staleTime: 1000 * 60 * 10,
cacheTime: 1000 * 60 * 15,
});
// 팔로워 랭킹 길이에 따른 정렬하기
const rankFollowerData = rankFollower?.sort((a: any, b: any) => {
if (a.follow.length < b.follow.length) {
return 1;
} else if (a.follow.length > b.follow.length) {
return -1;
} else {
return 0;
}
});
// 해당 유저 랭킹 번호 index로 나열하여 알아내기
const myRankNum = rankFollowerData?.map((item: any, index: any) => {
if (item.docId === authService.currentUser?.uid) return index;
});
const myRanking: any = myRankNum?.filter((item: any) => item > -1);
const myRank = rankFollower?.filter((item: any) => {
if (item.docId === authService.currentUser?.uid) {
return item;
}
});
//해당 유저 기준 앞,뒤 랭킹 데이터
const preRank = rankFollower?.slice(myRanking - 1, myRanking);
const nextRank = rankFollower?.slice(myRanking, myRanking + 1);
const nextRankNum = nextRank?.filter((item: any, index: any) => index === 1);
const { data: rankUser } = useQuery(['rankUser'], getUser, {
staleTime: 1000 * 60 * 10,
cacheTime: 1000 * 60 * 15,
});
댓글 랭킹
// 모든 포스트 데이터 가져오기
const { data: rankPost } = useQuery(['rankPost'], getData, {
staleTime: 1000 * 60 * 10,
cacheTime: 1000 * 60 * 15,
});
// 모든 유저 데이터 가져오기
const { data: rankUser } = useQuery(['rankUser'], getUser, {
staleTime: 1000 * 60 * 10,
cacheTime: 1000 * 60 * 15,
});
// 댓글 데이터 추출
const getCommentData = async () => {
const results = await Promise.all(
rankPost.map((item: any) =>
getComment({ queryKey: ['getCommentData', item.id] })
)
);
const commentsData = results
.filter((result: any) => result.length > 0)
.reduce((acc: any, cur: any) => {
return [...acc, ...cur];
}, []);
setCommentsDataList(commentsData);
};
// 유저 목록 추출
const users: string[] = Array.from(
new Set(rankPost?.map((post: RankPost) => post.creator))
);
// 유저별 포스트 추출
let userComments: RankUserPost[] = users.reduce<RankUserPost[]>(
(acc, user) => {
acc.push({
user,
posts: commentsDataList.filter(
(post: RankPost) => post.creatorUid === user
),
});
return acc;
},
[]
);
// 유저별 포스트 정렬
userComments.sort(function (a, b) {
if (a.posts.length < b.posts.length) {
return 1;
}
if (a.posts.length > b.posts.length) {
return -1;
}
return 0;
});
// 해당 유저 랭킹 데이터 호출
const myRankNum = userComments?.map((item: any, index: any) => {
if (item.user === authService.currentUser?.uid) return index;
});
const myRanking: any = myRankNum?.filter((item: any) => item > -1);
const myRank = userComments?.filter((item: any) => {
if (item.user === authService.currentUser?.uid) {
return item;
}
});
// 해당 유저 기준 앞,뒤 랭킹 데이터
const preRank = userComments?.slice(myRanking - 1, myRanking);
const nextRank = userComments?.slice(myRanking, myRanking + 1);
const nextRankNum = nextRank?.filter((item: any, index: any) => index === 1);
결과
'🌼 TIL' 카테고리의 다른 글
Virtual DOM (가상DOM) - React, Javascript (2) | 2023.10.26 |
---|---|
Vercel 빌드 중 " , ' 따옴표 오류 -> HTML 엔티티 (0) | 2023.10.23 |
저장(좋아요)기능 구현- Next.js, Firebase (0) | 2023.09.15 |
Next.js 이미지 최적화 작업 -Image 태그 (0) | 2023.09.11 |
데이터 모델링 개편으로 비효율적인 데이터 요청 줄이기 (0) | 2023.09.05 |