강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

s s님의 프로필 이미지
s s

작성한 질문수

React로 NodeBird SNS 만들기

6-14. 게시글 좋아요, 좋아요 취소

동작 오류 질문입니다

작성

·

104

0

삭제된 글입니다

답변 8

0

s s님의 프로필 이미지
s s
질문자

새로고침 후의 화면은 아래와 같습니다.

즉각적으로 변화하진 않고 새로고침 후의 변화하네요.

추가 적인 부분입니다.

로그를 찍어본 결과

좋아요 취소 버튼 클릭시 sagas/unlikePost.js -> back/routes/post.js의 /:id/like 부분 실행 그다음 PostCard.js에서 로그를 찍어보니 liked가 존재하는데 원래 이런가요? 원래 liked 값이 없어져야 정상 아닌가요??

백엔드 소스는 아래와 같습니다.

//좋아요 취소
router.delete('/:id/like'isLoggedInasync (reqresnext=> {
    console.log('백엔드 post.js delete 부분');
    try {
        const post = await db.Post.findOne({ where: { id: req.params.id}});
        if (!post) {
            return res.status(404).send('포스트가 존재하지 않습니다.');
        }
        //removeLiker가 되는게 model에서 sequelize는 자동으로 생성됨. as: 이부분 참조
        await post.removeLiker(req.user.id);
        res.json({ useId: req.user.id});
    } catch(e) {
        console.error(e);
        next(e);
    }
});

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

console.log(liked, post.Likers)를 onToggleLike 안에 넣어보세요.

0

s s님의 프로필 이미지
s s
질문자

위에 에러는 해결하였지만 시도해본 결과 좋아요 버튼 누르고 새로고침하면 좋아요가 활성화되어있고 새로고침 안할시에는 하트를 계속눌러도 좋아요 리퀘스트만 계속 가네요 즉 요약하자면 새로고침하면 적용되는것은 확인하였지만 새로고침 안할시에 적용이 안되는 것을 확인했습니다. 

const onToggleLike = useCallback(() => {
    if (!me) {
      return alert('로그인이 필요합니다');
    }
    
    //좋아요 누른상태
    if (liked) {
      dispatch({
        type: UNLIKE_POST_REQUEST,
        data: post.id,
      })
    } else { //좋아요 안누른 상태
      dispatch({
        type: LIKE_POST_REQUEST,
        data: post.id,
      });
    }
  }, [me && me.idpost && post.idliked]);

이 부분이 새로고침 안할시에는 계속 같은 요청을 하네요

예를들면 좋아요 버튼이 활성화 되어있으면 첫 클릭시 UNLIKE_POST_REQUEST, 두번쨰 클릭시 UNLIKE_POST_REQUEST 계속 같은 요청만 보내는 문제가 생겼습니다 이유가 뭔지 잘 모르겠습니다.

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

이 경우는 포스트를 등록할 때 제대로 addLiker가 되고 있지 않은 것 아닌가요? 좋아요를 누른 후 새로고침하면 게시글이 좋아요가 되어있나요?

0

s s님의 프로필 이미지
s s
질문자

서버에서 res.json 전에 로그를 찍어보니 user id 값은 잘나옵니다

프론트에서 로그 찍어본 결과 아래와 같습니다.

Likers 값이 없네요..

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

서버에서 res.json으로 userId 안 내려보내주나요?

0

s s님의 프로필 이미지
s s
질문자

말씀하신것 처럼 post.Likers의 아이디 값을 못받아오네요 

아래는 리듀서의 대한 소스입니다.

case LIKE_POST_REQUEST: {
        return {
          ...state,
        };
      }
      case LIKE_POST_SUCCESS: {
        const postIndex = state.mainPosts.findIndex(v => v.id === action.data.postId);
        const post = state.mainPosts[postIndex];
        const Likers = [{ id: action.data.userId }, ...post.Likers];
        const mainPosts = [...state.mainPosts];
        mainPosts[postIndex] = { ...postLikers };
        return {
          ...state,
          mainPosts,
        };
      }
      case LIKE_POST_FAILURE: {
        return {
          ...state,
        };
      }
      case UNLIKE_POST_REQUEST: {
        return {
          ...state,
        };
      }
      case UNLIKE_POST_SUCCESS: {
        const postIndex = state.mainPosts.findIndex(v => v.id === action.data.postId);
        const post = state.mainPosts[postIndex];
        const Likers = post.Likers.filter(v => v.id !== action.data.userId);
        const mainPosts = [...state.mainPosts];
        mainPosts[postIndex] = { ...postLikers };
        return {
          ...state,
          mainPosts,
        };
      }
      case UNLIKE_POST_FAILURE: {
        return {
          ...state,
        };
     }

아래는 sagas/post.js의 소스입니다.

//==============================================================
//좋아요
function likePostAPI(postId) {
  return axios.post(`/post/${postId}/like`, {}, {
    withCredentials: true,
  });
}

function* likePost(action) {
  try {
    const result = yield call(likePostAPIaction.data);
    yield put({
      type: LIKE_POST_SUCCESS,
      data: {
        postId: action.data,
        userId: result.data.userId,
      },
    });
  } catch (e) {
    console.error(e);
    yield put({
      type: LIKE_POST_FAILURE,
      error: e,
    });
  }
}

function* watchLikePost() {
  yield takeLatest(LIKE_POST_REQUESTlikePost);
}

//==============================================================
//좋아요 취소
function unlikePostAPI(postId) {
  return axios.delete(`/post/${postId}/like`, {
    withCredentials: true,
  });
}

function* unlikePost(action) {
  try {
    const result = yield call(unlikePostAPIaction.data);
    yield put({
      type: UNLIKE_POST_SUCCESS,
      data: {
        postId: action.data,
        userId: result.data.userId,
      },
    });
  } catch (e) {
    console.error(e);
    yield put({
      type: UNLIKE_POST_FAILURE,
      error: e,
    });
  }
}

function* watchUnlikePost() {
  yield takeLatest(UNLIKE_POST_REQUESTunlikePost);
}

export default function* postSaga() {
  yield all([
    fork(watchLoadMainPosts),
    fork(watchAddPost),
    fork(watchAddComment),
    fork(watchLoadComments),
    fork(watchLoadHashtagPosts),
    fork(watchLoadUserPosts),
    fork(watchUploadImages),
    fork(watchLikePost),
    fork(watchUnlikePost),
  ]);
}

아래는 back/models/post.js의 대한 소스입니다.

module.exports = (sequelizeDataTypes=> {
    const Post = sequelize.define('Post', {
        content: {
            type: DataTypes.TEXT,
            allowNull: false,
        },
    }, {
        charset: 'utf8mb4'//한글+ 이모티콘
        collate: 'utf8mb4_general_ci',
    });

    Post.associate = (db=>{
        db.Post.belongsTo(db.User); // 테이블에 UserId 컬럼이 생겨요
        db.Post.hasMany(db.Comment);
        db.Post.hasMany(db.Image);
        db.Post.belongsTo(db.Post, { as: 'Retweet' }); // RetweetId 컬럼 생겨요
        db.Post.belongsToMany(db.Hashtag, { through: 'PostHashtag' });
        db.Post.belongsToMany(db.User, { through: 'Like'as: 'Likers' });
    };

    return Post;
}

아래는 back/routes/post.js의 소스입니다.

router.post('/:id/like'isLoggedInasync (reqresnext=> {
    try {
        const post = await db.Post.findOne({ where: { id: req.params.id}});
        if (!post) {
            return res.status(404).send('포스트가 존재하지 않습니다.');
        }
        await post.addLiker(req.user.id);
        res.json({ useId: req.user.id});
    } catch(e) {
        console.error(e);
        next(e);
    }
});

router.delete('/:id/like'isLoggedInasync (reqresnext=> {
    try {
        const post = await db.Post.findOne({ where: { id: req.params.id}});
        if (!post) {
            return res.status(404).send('포스트가 존재하지 않습니다.');
        }
        await post.removeLiker(req.user.id);
        res.json({ useId: req.user.id});
    } catch(e) {
        console.error(e);
        next(e);
    }
});

module.exports = router;

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

liked는 post.Likers.find 이 부분을 사용합니다. post.Likers에 사용자 아이디가 추가 안 되는 것 같고요.

이 부분은 리듀서 점검해보셔야 할 것 같습니다.

s s님의 프로필 이미지
s s

작성한 질문수

질문하기