-
카테고리
-
세부 분야
풀스택
-
해결 여부
해결됨
리트윗 라우터에서 설정한 리트윗 검사가 되지 않습니다!(중복 리트윗 체크 및 본인 게시글 리트윗이 막아지지 않는 문제)
24.01.02 20:29 작성 24.01.03 00:45 수정 조회수 144
1
안녕하세요! React로 NodeBird SNS 만들기
섹션4 리트윗하기 강의 시청 중 발생한 에러에 대해 질문 드립니다!
항상 강의 잘 보고 있습니다! 제로초님 감사합니다!
[리트윗 라우터에서 설정한 리트윗 검사]
1. 자기 게시글을 리트윗한 경우
2. 자기 게시글을 리트윗한 다른 게시글을 다시 자기가 리트윗한 경우
3. 이미 리트윗한 게시글을 또 리트윗 하는 경우(중복 리트윗)
여러 개의 게시글을 가져오는 라우터에서 리트윗한 게시글, 작성자, 이미지 모델을 넣었으며,
게시글 Reducer에서 리트윗 실패 시 실패 확인을 'draft.retweetError = action.error;'로 확인하였습니다.
게시글 Saga에서도 리트윗 요청 실패 시 실패 결과를 'error: err.response.data'로 설정했습니다.
★ 프론트, 백엔드 쪽 터미널과 콘솔, 리덕스, 네티워크 쪽에 오류가 없음을 확인하였습니다.
코드 오타가 원인이라고 파악해 제로초님의 깃허브와 제 코드를 비교하며 확인했으나
원인을 찾을 수 없어 질문 올립니다. 아래는 가장 의심되는 코드 입니다.
중요하지 않은 코드는 '. . .' 으로 생략하였습니다.
front/pages/index.js
// React 라이브러리 훅 불러오기
import React, { useEffect } from 'react';
. . .
// 홈 컴포넌트(사용자 정의 태그)
const Home = () => {
const dispatch = useDispatch();
const { me } = useSelector((state) => state.user);
const { mainPosts, hasMorePosts, loadPostsLoading, retweetError } = useSelector((state) => state.post);
. . .
// 리트윗 실패 시 리트윗 에러 alert 창 띄우기
useEffect(() => {
if (retweetError) {
alert(retweetError);
}
}, [retweetError]);
front/components/PostCard.js
따로 게시글을 리트윗 실패(RETWEET_FAILURE) 액션을 디스패치 해야 하는지 의심이 들었습니다!
// 게시글 카드 컴포넌트(사용자 정의 태그)
const PostCard = ({ post }) => {
. . .
// 리트윗 버튼 콜백 함수
const onRetweet = useCallback(() => {
// 로그인을 안했을 때 '로그인이 필요합니다.' alert 창 띄우기
if (!id) {
return alert('로그인이 필요합니다.');
}
/* 리트윗 요청 액션 객체 디스패치 */
return dispatch({
type: RETWEET_REQUEST, // 리트윗 요청 액션
data: post.id, // 게시글 아이디
});
}, [id]);
. . .
return (
<div style={{ marginBottom: '20px' }}>
<Card
/* ---------- 이미지 : 이미지는 1개 이상 ---------- */
cover={post.Images[0] && <PostImages images={post.Images} />}
/* ---------- 액션 버튼 ---------- */
actions={[
/* ---------- 리트윗 버튼 ---------- */
<RetweetOutlined key="retweet" onClick={onRetweet} />,
. . .
]}
/* 카드 제목 */
title={post.RetweetId
// 리트윗 게시글이면 게시글 사용자 닉네임님이 리트윗 하셨습니다. 제목 써주기
? `${post.User.nickname}님이 리트윗 하셨습니다.`
// 일반 게시글이면 제목 안 써주기
: null
}
. . .
> {/* Card 닫기 */}
{/* ---------- 리트윗 게시글 ---------- */}
{post.RetweetId && post.Retweet
? (
<Card
/* ---------- 이미지 : 이미지는 1개 이상 ---------- */
cover={post.Retweet.Images[0]
&& <PostImages images={post.Retweet.Images} />}
>
<Card.Meta
// 메인 게시글 리트윗한 사용자 닉네임의 첫 번째 글자를
// 아바타 아이콘으로 표시
avatar={<Avatar>{post.Retweet.User.nickname[0]}</Avatar>}
// 메인 게시글 리트윗한 게시글 작성자 이름
title={post.Retweet.User.nickname}
// 메인 게시글 게시글 콘텐츠
description={<PostCardContent postData={post.Retweet.content} />}
/>
</Card>
)
: (
/* ---------- (리트윗을 하지않은) 일반 게시글 ---------- */
<Card.Meta
// 메인 게시글 사용자 닉네임의 첫 번째 글자를 아바타 아이콘으로 표시
avatar={<Avatar>{post.User.nickname[0]}</Avatar>}
// 메인 게시글 작성자 이름
title={post.User.nickname}
// 메인 게시글 콘텐츠
description={<PostCardContent postData={post.content} />}
/>
)}
</Card>
back/routes/post.js
// 리트윗 라우터
router.post('/:postId/retweet', isLoggedIn, async (req, res, next) => { // POST /post/동적 히든/retweet
try {
/* 존재하지 않는 게시글이 있는지 검사하는 함수 */
const post = await Post.findOne({
where: { id: req.params.postId },
// 모델 가져오기
include: [{
model: Post,
as: 'Retweet', // as: 'Retweet'으로 include를 해주면 post.retweet이 생긴다.
}],
});
/* ---------- 만약 존재하지 않는 게시글이 있다면 400번대 에러 출력 ---------- */
if (!post) {
return res.status(403).send('존재하지 않는 게시글입니다.');
}
/* 자기 게시글을 리트윗하기
or 자기 게시글을 리트윗한 다른 게시글을 다시 자기가 리트윗하기 막기 */
if (req.user.id === post.UserId
|| (post.Retweet && post.Retweet.UserId === req.user.id)) {
return res.status(403).send('자신의 글은 리트윗할 수 없습니다.');
}
// 리트윗할 Id : 리트윗한 게시글이면 리트윗 아이디 사용 or 아니면 게시글 아이디 사용
const retweetTargetId = post.RetweetId || post.id;
/* 이미 리트윗한 게시글을 또 리트윗하는지 검사하는 함수(두 번 리트윗 막기) */
const exPost = await Post.findOne({
where: {
UserId: req.user.id,
RetweetId: retweetTargetId,
},
});
/* ----- 만약 이미 리트윗한 게시글을 또 리트윗한다면 400번대 에러 출력 ----- */
if (exPost) {
return res.status(403).send('이미 리트윗했습니다.');
}
/* await : 실제로 데이터가 들어감, create : 테이블 안에 데이터를 넣음 */
const retweet = await Post.create({
UserId: req.user.id,
RetweetId: retweetTargetId,
content: 'retweet',
// 게시글 모델에서 allowNull을 false로 설정했기 때문에 게시글 콘텐츠가 필수다.
});
/* ---------- 내가 어떤 게시글을 리트윗했는지 찾는 함수 ---------- */
const retweetWithPrevPost = await Post.findOne({
where: { id: retweet.id },
// 모델 가져오기
include: [{
/* ---------- 리트윗한 게시글 ---------- */
model: Post,
as: 'Retweet', // 리트윗한 게시글이 post.Retweet으로 담긴다.
// 모델 가져오기
include: [{
/* ---------- 리트윗한 게시글의 작성자 ---------- */
model: User,
attributes: ['id', 'nickname'], // id, nickname 데이터만 가져오기
}, {
/* ---------- 리트윗한 게시글의 이미지 ---------- */
model: Image,
}]
}, {
/* ---------- 게시글 작성자 ---------- */
model: User,
attributes: ['id', 'nickname'], // id, nickname 데이터만 가져오기
}, {
/* ---------- 게시글 좋아요 누른 사람들 ---------- */
model: User,
as: 'Likers',
attributes: ['id'], // id 데이터만 가져오기
}, {
/* ---------- 게시글 이미지 ---------- */
model: Image,
}, {
/* ---------- 게시글 답글 ---------- */
model: Comment,
// 모델 가져오기
include: [{
/* ---------- 게시글 답글의 작성자 ---------- */
model: User,
attributes: ['id', 'nickname'], // id, nickname 데이터만 가져오기
}],
}],
});
/* 게시글 작성 성공 시 어떤 게시글을 리트윗 했는지에 대한 정보를 프론트로 돌려주기 */
res.status(201).json(retweetWithPrevPost);
/* ---------- 에러 캐치 ---------- */
} catch (error) {
console.error(error);
next(error);
}
});
+++ 줄바꿈이 되지 않은 문제를 수정하였습니다.
답변을 작성해보세요.
0
조현영
지식공유자2024.01.02
req.user.id, post.Retweet, post.UserId, exPost 같은 것들 전부를 console.log 해서 체크해보시면 되겠죠?
이가은
질문자2024.01.02
콘솔에 찍히지 않습니다! post 라우터 쪽에서 해당하는 위치에 콘솔로그를 했습니다.
console.log(req.user.id);
console.log(post.Retweet);
console.log(post.UserId);
console.log(exPost);
++
MySQL을 확인해보니 userId는 있지만 RetweetId가 null로 찍혀있었습니다.
리덕스에서 리트윗 버튼을 누르면 RETWEET_REQUEST 요청 액션만 간 것입니다!
이가은
질문자2024.01.03
네트워크 탭에는 문제가 없습니다!
saga catch쪽에는 문제가 없었으나 리트윗 액션 쪽에서 yield를 쓰지 않아 발생한 문제였습니다!
// 리트윗 액션 수정 전
function* watchRetweet() {
takeLatest(RETWEET_REQUEST, retweet);
}
// 리트윗 액션 수정 후
function* watchRetweet() {
yield takeLatest(RETWEET_REQUEST, retweet);
}
이제 리트윗 검사가 정상적으로 실행되고, MySQL에서 RetweetId가 정상적으로 숫자로 들어갑니다!
늦은 시간에 질문을 올려서 죄송하고 끝까지 알려주셔서 정말로 감사합니다 제로초님!!
0
인프런 AI 인턴
2024.01.02
안녕하세요, 인프런 AI 인턴입니다.
이가은님께서 질문하신 ‘리트윗 라우터에서 설정한 리트윗 검사가 되지 않습니다!‘에 대해 이전에 비슷한 주제로 질문하신 다른 수강생분들의 질문과 강사님의 답변이 도움이 될 것 같습니다.
다음은 리트윗 관련 문제와 해결 방법에 대한 질문과 강사님의 답변이 담긴 게시물 링크입니다. 참고하시면 문제를 해결하는 데 도움이 될 것입니다.
제목: retweet 관련 질문이 있습니다.
retweet 관련 질문이 있습니다.제목: 403 에러 발생시에 retweetError 가 null 로 찍혀여
403 에러 발생시에 retweetError 가 null 로 찍혀여제목: 글쓰기? 리트윗? 새로고침 오류
글쓰기? 리트윗? 새로고침 오류
이러한 경우들을 참고하셔서 코드를 다시 검토해 보시는 것도 좋은 접근 방법일 것 같습니다.
답변 3