diff --git a/src/components/detail/CommentView.test.tsx b/src/components/detail/CommentView.test.tsx
index 9e32b7c6..dbf5641e 100644
--- a/src/components/detail/CommentView.test.tsx
+++ b/src/components/detail/CommentView.test.tsx
@@ -10,14 +10,14 @@ describe('CommentView', () => {
const renderCommentView = () => render((
));
context('댓글 작성자인 경우', () => {
- given('user', () => PROFILE_FIXTURE);
+ given('userUid', () => PROFILE_FIXTURE.uid);
describe('삭제 버튼을 클릭한다', () => {
it('클릭 이벤트가 발생해야만 한다', () => {
@@ -25,16 +25,15 @@ describe('CommentView', () => {
fireEvent.click(screen.getByText('삭제'));
- expect(handleRemove).toHaveBeenCalledWith(COMMENT_FIXTURE.commentId);
+ expect(handleRemove).toHaveBeenCalledWith({
+ commentId: COMMENT_FIXTURE.commentId, groupId: COMMENT_FIXTURE.groupId,
+ });
});
});
});
context('댓글 작성자가 아닌 경우', () => {
- given('user', () => ({
- ...PROFILE_FIXTURE,
- uid: '1',
- }));
+ given('userUid', () => '1');
it('삭제 버튼이 나타나지 않아야 한다', () => {
const { container } = renderCommentView();
diff --git a/src/components/detail/CommentView.tsx b/src/components/detail/CommentView.tsx
index 1160b072..eb479d58 100644
--- a/src/components/detail/CommentView.tsx
+++ b/src/components/detail/CommentView.tsx
@@ -5,7 +5,7 @@ import {
import styled from '@emotion/styled';
import dayjs from 'dayjs';
-import { Profile } from '@/models/auth';
+import { DeleteCommentForm } from '@/hooks/api/comment/useDeleteComment';
import { Comment } from '@/models/group';
import { body1Font, body2Font, subtitle1Font } from '@/styles/fontStyles';
import { filteredWithSanitizeHtml } from '@/utils/filter';
@@ -15,17 +15,25 @@ import ProfileImage from '../common/ProfileImage';
interface Props {
comment: Comment;
- user: Profile | null;
- onRemove: (commentId: string) => void;
+ userUid: string | undefined;
+ onRemove: ({ commentId, groupId }: DeleteCommentForm) => void;
}
+const commentViewPropsAreEqual = (prevProps: Props, nextProps: Props) => (
+ prevProps.comment.commentId === nextProps.comment.commentId
+ && prevProps.userUid === nextProps.userUid
+ && prevProps.onRemove === nextProps.onRemove
+ && prevProps.comment.writer.uid === nextProps.comment.writer.uid
+ && prevProps.comment.groupId === nextProps.comment.groupId
+);
+
function CommentView({
- comment, user, onRemove,
+ comment, userUid, onRemove,
}: Props, ref: ForwardedRef): ReactElement {
const {
- writer, content, createdAt, commentId,
+ content, createdAt, commentId, groupId, writer,
} = comment;
- const isWriter = user?.uid === writer.uid;
+ const isWriter = userUid === writer.uid;
return (
@@ -40,7 +48,7 @@ function CommentView({
{isWriter && (
onRemove(commentId)}
+ onClick={() => onRemove({ commentId, groupId })}
>
삭제
@@ -52,7 +60,7 @@ function CommentView({
);
}
-export default memo(forwardRef(CommentView));
+export default memo(forwardRef(CommentView), commentViewPropsAreEqual);
const CommentStatus = styled.div`
display: flex;
diff --git a/src/components/detail/CommentsView.test.tsx b/src/components/detail/CommentsView.test.tsx
index f81e0efd..5a50b0a5 100644
--- a/src/components/detail/CommentsView.test.tsx
+++ b/src/components/detail/CommentsView.test.tsx
@@ -1,5 +1,6 @@
import { fireEvent, render, screen } from '@testing-library/react';
+import useDeleteComment from '@/hooks/api/comment/useDeleteComment';
import useInfiniteFetchComments from '@/hooks/api/comment/useInfiniteFetchComments';
import COMMENT_FIXTURE from '../../../fixtures/comment';
@@ -8,6 +9,7 @@ import PROFILE_FIXTURE from '../../../fixtures/profile';
import CommentsView from './CommentsView';
jest.mock('@/hooks/api/comment/useInfiniteFetchComments');
+jest.mock('@/hooks/api/comment/useDeleteComment');
describe('CommentsView', () => {
const handleRemove = jest.fn();
@@ -27,13 +29,16 @@ describe('CommentsView', () => {
lastItemRef,
},
}));
+
+ (useDeleteComment as jest.Mock).mockImplementation(() => ({
+ mutate: handleRemove,
+ }));
});
const renderCommentsView = () => render((
));
@@ -53,7 +58,9 @@ describe('CommentsView', () => {
fireEvent.click(screen.getByText('삭제'));
- expect(handleRemove).toHaveBeenCalledWith(COMMENT_FIXTURE.commentId);
+ expect(handleRemove).toHaveBeenCalledWith({
+ commentId: COMMENT_FIXTURE.commentId, groupId: COMMENT_FIXTURE.groupId,
+ });
});
});
});
diff --git a/src/components/detail/CommentsView.tsx b/src/components/detail/CommentsView.tsx
index a47a7f3f..01247a7b 100644
--- a/src/components/detail/CommentsView.tsx
+++ b/src/components/detail/CommentsView.tsx
@@ -1,27 +1,31 @@
-import { memo, ReactElement } from 'react';
+import { ReactElement, useCallback } from 'react';
import styled from '@emotion/styled';
+import useDeleteComment, { DeleteCommentForm } from '@/hooks/api/comment/useDeleteComment';
import useInfiniteFetchComments from '@/hooks/api/comment/useInfiniteFetchComments';
-import { Profile } from '@/models/auth';
import { targetFalseThenValue } from '@/utils/utils';
import CommentSkeletonLoader from './CommentSkeletonLoader';
import CommentView from './CommentView';
interface Props {
- user: Profile | null;
+ userUid: string | undefined;
perPage: number;
- onRemove: (commentId: string) => void;
}
-function CommentsView({ user, perPage, onRemove }: Props): ReactElement {
+function CommentsView({ userUid, perPage }: Props): ReactElement {
const { query: { data, isFetchingNextPage }, refState } = useInfiniteFetchComments({
perPage,
});
+ const { mutate: deleteCommentMutate } = useDeleteComment(perPage);
const comments = data.pages;
+ const onRemoveComment = useCallback((
+ commentForm: DeleteCommentForm,
+ ) => deleteCommentMutate(commentForm), []);
+
return (
{comments.map(({ items }) => (
@@ -31,8 +35,8 @@ function CommentsView({ user, perPage, onRemove }: Props): ReactElement {
return (
@@ -46,7 +50,7 @@ function CommentsView({ user, perPage, onRemove }: Props): ReactElement {
);
}
-export default memo(CommentsView);
+export default CommentsView;
const CommentsViewWrapper = styled.div`
& > div:last-of-type {
diff --git a/src/components/home/TagsBar.tsx b/src/components/home/TagsBar.tsx
index a51fd900..e19c7bdc 100644
--- a/src/components/home/TagsBar.tsx
+++ b/src/components/home/TagsBar.tsx
@@ -1,4 +1,4 @@
-import { memo, ReactElement } from 'react';
+import { ReactElement } from 'react';
import styled from '@emotion/styled';
import { useSetRecoilState } from 'recoil';
@@ -29,7 +29,7 @@ function TagsBar(): ReactElement {
);
}
-export default memo(TagsBar);
+export default TagsBar;
const TagsWrapper = styled.div`
height: 36px;
diff --git a/src/components/myInfo/SettingForm.tsx b/src/components/myInfo/SettingForm.tsx
index 9824d5c3..5f8199a6 100644
--- a/src/components/myInfo/SettingForm.tsx
+++ b/src/components/myInfo/SettingForm.tsx
@@ -1,6 +1,4 @@
-import {
- memo, ReactElement, useEffect, useState,
-} from 'react';
+import { ReactElement, useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { useEffectOnce, useUpdateEffect } from 'react-use';
@@ -133,7 +131,7 @@ function SettingForm({
);
}
-export default memo(SettingForm);
+export default SettingForm;
const MemberWithdrawalButton = styled(Button)`
color: ${({ theme }) => theme.accent6};
diff --git a/src/containers/detail/CommentsContainer.test.tsx b/src/containers/detail/CommentsContainer.test.tsx
index b9819674..fe74f66f 100644
--- a/src/containers/detail/CommentsContainer.test.tsx
+++ b/src/containers/detail/CommentsContainer.test.tsx
@@ -21,7 +21,7 @@ jest.mock('@/hooks/api/comment/useAddComment');
jest.mock('next/router', () => ({
useRouter: jest.fn().mockImplementation(() => ({
query: {
- id: '1',
+ id: COMMENT_FIXTURE.groupId,
},
})),
}));
@@ -90,7 +90,7 @@ describe('CommentsContainer', () => {
expect(mutate).toHaveBeenCalledWith({
content: commentValue,
writer,
- groupId: '1',
+ groupId: COMMENT_FIXTURE.groupId,
});
});
@@ -102,7 +102,7 @@ describe('CommentsContainer', () => {
expect(mutate).toHaveBeenCalledWith({
commentId: COMMENT_FIXTURE.commentId,
- groupId: '1',
+ groupId: COMMENT_FIXTURE.groupId,
});
});
});
diff --git a/src/containers/detail/CommentsContainer.tsx b/src/containers/detail/CommentsContainer.tsx
index e605a73a..e9d1284f 100644
--- a/src/containers/detail/CommentsContainer.tsx
+++ b/src/containers/detail/CommentsContainer.tsx
@@ -11,7 +11,6 @@ import CommentForm from '@/components/detail/CommentForm';
import CommentSkeletonLoader from '@/components/detail/CommentSkeletonLoader';
import useFetchUserProfile from '@/hooks/api/auth/useFetchUserProfile';
import useAddComment from '@/hooks/api/comment/useAddComment';
-import useDeleteComment from '@/hooks/api/comment/useDeleteComment';
import useFetchCommentCount from '@/hooks/api/comment/useFetchCommentCount';
import { GroupQuery } from '@/models';
import { CommentFields } from '@/models/group';
@@ -28,16 +27,11 @@ function CommentsContainer(): ReactElement {
const { data: user } = useFetchUserProfile();
const { data: commentCount } = useFetchCommentCount(groupId);
const { mutate: addCommentMutate } = useAddComment(perPage);
- const { mutate: deleteCommentMutate } = useDeleteComment(perPage);
const onSubmit = useCallback((commentForm: CommentFields) => addCommentMutate({
...commentForm,
groupId,
- }), [groupId, addCommentMutate]);
-
- const onRemoveComment = useCallback((commentId: string) => deleteCommentMutate({
- commentId, groupId,
- }), [groupId, deleteCommentMutate]);
+ }), [groupId]);
return (
<>
@@ -50,9 +44,8 @@ function CommentsContainer(): ReactElement {
}>
diff --git a/src/hooks/api/comment/useDeleteComment.ts b/src/hooks/api/comment/useDeleteComment.ts
index 007d5b8c..3037fe23 100644
--- a/src/hooks/api/comment/useDeleteComment.ts
+++ b/src/hooks/api/comment/useDeleteComment.ts
@@ -11,7 +11,7 @@ import useCatchFirestoreErrorWithToast from '../useCatchFirestoreErrorWithToast'
import { deleteCommentQueryData } from './queryDataUtils';
-type DeleteCommentForm = {
+export type DeleteCommentForm = {
commentId: string;
groupId: string;
};