Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 17 additions & 21 deletions src/features/projects/hook/useLike.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState } from "react";
import { useParams } from "react-router-dom";

import useProjectLike from "@features/projects/queries/useProjectLike";
import useProjectUnLike from "@features/projects/queries/useProjectUnLike";
Expand All @@ -7,48 +8,43 @@ import { useAuthStore } from "@shared/stores/authStore";

interface LikeResult {
isLike: boolean;
like: () => void;
unlike: () => void;
likeFn: () => void;
}

const useLike = ({
projectID,
likedUsers,
}: {
projectID: string;
likedUsers: string[];
}): LikeResult => {
const useLike = ({ likedUsers }: { likedUsers: string[] }): LikeResult => {
const { id: projectID } = useParams();
const user = useAuthStore((state) => state.user);
const { mutate: updateLike, isPending: likePending } = useProjectLike();
const { mutate: updateUnLike, isPending: unLikePending } = useProjectUnLike();

const initLike = user && likedUsers.includes(user.uid);
const [isLike, setIsLike] = useState(initLike || false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 isLike 상태를 useState로만 관리하고 있는데,
유저 프로필에서 프로젝트 리스트 삭제 기능을 추가하면서 관심/좋아요 리스트를 전역상태 관리로 바꿨는데
프로필에서 관심 프로젝트를 삭제하면 디테일 페이지의 UI와 상태가 불일치 할 수도? 있을 것 같아요🥲

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

관심/좋아요 리스트를 전역상태로 바꿧다는 말은 api 호출로 db값을 수정하지않는다는 말씀이신가요 ?
상세페이지의 좋아요 여부 체크는 게시글(projects 컬렉션)에 등록된 좋아요한 유저 목록을 api로 불러와 현재 로그인 한 사용자의 id와 비교하여 보여주므로 프로필의 전역상태와는 무관할 것 같습니다 😀

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엇 아니요 ! 전역 상태만 바꾸는 게 아니라, 반드시 API로 DB(파이어베이스) 값을 먼저 수정하고,
그 결과를 전역 상태에 반영해서 UI를 동기화한다는 말이었어요 !
상세페이지와 프로필 등 여러 곳에서 관심/좋아요 상태가 항상 일치하려면,
DB와 전역 상태를 항상 동기화하는 구조가 안전하지 않을까 생각합니다 !

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 네~
상세 페이지에서는 항상 최신 상태의 db값을 들고오며 user 프로필에서 uid 값 이외엔 사용하지 않으니 수정하지 않아도 괜찮을 것 같습니다 😉


const like = (): void => {
const updateLikeStatus = (): void => {
if (!projectID) return;
if (likePending || unLikePending) {
alert("동작이 너무 빠릅니다. 잠시 후에 시도해주십시오.");

if (!user) {
alert("로그인 해주세요.");
return;
}
setIsLike(true);
updateLike(projectID);
};

const unlike = (): void => {
if (!projectID) return;
if (likePending || unLikePending) {
alert("동작이 너무 빠릅니다. 잠시 후에 시도해주십시오.");
return;
}
setIsLike(false);
updateUnLike(projectID);

if (!isLike) {
setIsLike(true);
updateLike(projectID);
} else {
setIsLike(false);
updateUnLike(projectID);
}
Comment on lines +36 to +42
Copy link
Contributor

@tkyoun0421 tkyoun0421 Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

비슷한 로직인 것 같아서 하나의 함수에서 관리하는 게 좋을 것 같다고 생각이 들어서 고민해보다가
근데 또 그렇게 생각해보니 복잡도가 좀 더 올라가는 부분이 있는 것 같아서..
어렵네요 개발 😢

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그쵸 ㅠㅠ api 부터 합칠까 고민했는데
넣고 빼는 행위 따라서 구분하는게 추후에 알아보기 더 쉬울거같아서 결국 나누었습니다😇

};

return {
isLike,
like,
unlike,
likeFn: updateLikeStatus,
};
};

Expand Down
18 changes: 9 additions & 9 deletions src/features/projects/ui/ProjectLike.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ import FavoriteBorderIcon from "@mui/icons-material/FavoriteBorder";
import FavoriteOutlinedIcon from "@mui/icons-material/FavoriteOutlined";
import ShareIcon from "@mui/icons-material/Share";
import { Box, styled } from "@mui/material";
import { useParams } from "react-router-dom";

import useLike from "@features/projects/hook/useLike";

import { getStatusClassname } from "@shared/libs/utils/projectDetail";
import {
getStatusClassname,
shareProjectUrl,
} from "@shared/libs/utils/projectDetail";
import type { ProjectListRes } from "@shared/types/project";

type ProjectLikeType = Pick<ProjectListRes, "status" | "likedUsers">;

const ProjectLike = ({ values }: { values: ProjectLikeType }): JSX.Element => {
const { id } = useParams();
const { like, unlike, isLike } = useLike({
projectID: id || "",
const { likeFn, isLike } = useLike({
likedUsers: values.likedUsers,
});

Expand All @@ -26,14 +26,14 @@ const ProjectLike = ({ values }: { values: ProjectLikeType }): JSX.Element => {
</StatusBox>

<Box display="flex">
<HeadIconBox>
<HeadIconBox onClick={likeFn}>
{isLike ? (
<FavoriteOutlinedIcon color="error" onClick={unlike} />
<FavoriteOutlinedIcon color="error" />
) : (
<FavoriteBorderIcon onClick={like} />
<FavoriteBorderIcon />
)}
</HeadIconBox>
<HeadIconBox>
<HeadIconBox onClick={shareProjectUrl}>
<ShareIcon />
</HeadIconBox>
</Box>
Expand Down
7 changes: 7 additions & 0 deletions src/shared/libs/utils/projectDetail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,10 @@ export const formatDate = (date?: string | Timestamp): string => {
}
return date;
};

export const shareProjectUrl = (): void => {
navigator.clipboard
.writeText(window.location.href)
.then(() => alert("URL이 복사되었습니다."))
.catch(() => alert("복사 실패"));
Comment on lines +21 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 웹 API네요 또 하나 배워갑니다 :)
감사합니다 🙇

};