-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[김주동] sprint10 #124
The head ref may contain hidden characters: "Next-\uAE40\uC8FC\uB3D9-sprint10"
[김주동] sprint10 #124
Conversation
React 김주동 sprint6
* First commit Sprint Mission5 on React * Sprint mission 6 commit. * Sprint Mission 6 Update 1 * update sprint mission 6 * Sprint mission 6 update commit. * delete .bak files * Update Comments * modify ItemComment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
주동님 이번 스프린트 미션 고생하셨습니다~
try { | ||
const query = new URLSearchParams(params).toString(); | ||
const response = await fetch( | ||
`https://panda-market-api.vercel.app/articles/${articleId}/comments?${query}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3:
공통으로 사용되는 기본 주소는 변수에 저장해두고 쓰셔도 좋을 것 같아요
`https://panda-market-api.vercel.app/articles/${articleId}/comments?${query}` | |
`${BASE_URL}/articles/${articleId}/comments?${query}` |
|
||
type ArticleItemProps = { | ||
interface ArticleItemProps { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3:
interface로 바꿔주신것 좋습니다 👍
{article.writer.nickname} <Timestamp>{dateString}</Timestamp> | ||
</ArticleInfoDiv> | ||
<ArticleInfoWrapper> | ||
<ArticleInfo article={article} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3:
기존 ArticleInfoDiv
에서 ArticleInfo
태그명을 빼주신게 좋네요.
<CommentSectionTitle>댓글 달기</CommentSectionTitle> | ||
|
||
<TextArea | ||
placeholder={"댓글을 입력해 주세요."} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3:
placeholder={"댓글을 입력해 주세요."} | |
placeholder="댓글을 입력해 주세요." |
const handleInputChange = (e: ChangeEvent<HTMLTextAreaElement>) => { | ||
setComment(e.target.value); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2:
이렇게 인풋값이 입력될때마다 state를 바꿔주는 경우 debounce를 통해 이벤트를 묶어 실행해주시는 것이 좋습니다.
그렇게 되면 리렌더링되는 횟수를 줄일 수 있습니다.
const ArticlePageCommentThread: React.FC<ArticlePageCommentThreadProps> = ({ | ||
articleId, | ||
}) => { | ||
const [comments, setComments] = useState<Comment[]>([]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3:
배열의 타입 명시해준거 좋습니다 👍
useEffect(() => { | ||
if (!articleId) return; | ||
|
||
const fetchComments = async () => { | ||
setIsLoading(true); | ||
|
||
try { | ||
const response: CommentListResponse = await getArticleComments({ | ||
articleId, | ||
}); | ||
setComments(response.list); | ||
setError(null); | ||
} catch (error) { | ||
console.error("Error fetching comments:", error); | ||
setError("게시글의 댓글을 불러오지 못했어요."); | ||
} finally { | ||
setIsLoading(false); | ||
} | ||
}; | ||
|
||
fetchComments(); | ||
}, [articleId]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3:
아래처럼 fetchComments 함수를 useEffect 외부로 빼셔도 됩니다.
이렇게 되면 로직이 분리되어 가독성에도 도움이 됩니다.
const fetchComments = useCallback(async () => {
setIsLoading(true);
try {
const response: CommentListResponse = await getArticleComments({
articleId,
});
setComments(response.list);
setError(null);
} catch (error) {
console.error("Error fetching comments:", error);
setError("게시글의 댓글을 불러오지 못했어요.");
} finally {
setIsLoading(false);
}
});
useEffect(() => {
if (!articleId) return;
fetchComments();
}, [articleId, fetchComments]);
if (comments && !comments.length) { | ||
return ( | ||
<EmptyState text={`아직 댓글이 없어요,\n지금 댓글을 달아 보세요!`} /> | ||
); | ||
} else { | ||
return ( | ||
<ThreadContainer> | ||
{comments.map((item) => ( | ||
<CommentItem item={item} key={`comment-${item.id}`} /> | ||
))} | ||
</ThreadContainer> | ||
); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2:
이미 comments && !comments.length 조건문에서 return을 하고 있으니 else문은 사용하지 않으셔도 됩니다.
if (comments && !comments.length) { | |
return ( | |
<EmptyState text={`아직 댓글이 없어요,\n지금 댓글을 달아 보세요!`} /> | |
); | |
} else { | |
return ( | |
<ThreadContainer> | |
{comments.map((item) => ( | |
<CommentItem item={item} key={`comment-${item.id}`} /> | |
))} | |
</ThreadContainer> | |
); | |
} | |
}; | |
if (comments && !comments.length) { | |
return ( | |
<EmptyState text={`아직 댓글이 없어요,\n지금 댓글을 달아 보세요!`} /> | |
); | |
} | |
return ( | |
<ThreadContainer> | |
{comments.map((item) => ( | |
<CommentItem item={item} key={`comment-${item.id}`} /> | |
))} | |
</ThreadContainer> | |
); | |
}; |
const [comments, setComments] = useState<Comment[]>([]); | ||
const [isLoading, setIsLoading] = useState(false); | ||
const [error, setError] = useState<string | null>(null); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3:
data, isLoading, error와 같은 state들이 있고 이에 따른 로직들이 반복되니 custom hook으로 분리하시면 더 좋을 것 같아요~
id="image-upload" | ||
type="file" | ||
onChange={handleImageChange} | ||
accept="image/*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3:
file의 accept 속성은 user에게 적힌 확장자를 제안할뿐 제한하는 것은 아닙니다.
특정 확장자만 받고 싶다면 handleImageChange
함수에서 해당 file의 확장자를 확인하신 후 이에 따른 로직을 입력해주셔야 합니다.
요구사항
기본
심화
주요 변경사항
스크린샷
멘토에게