You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Redux点赞/取消点赞功能前端异常问题求助

点赞功能问题排查与修复方案

后端问题修复

1. JWT验证与用户查询错误

  • 问题:const user = User.findByPk(userId);未使用await,导致user为Promise对象,无法正确判断用户是否存在;若前端请求未携带Cookie,req.cookies.jwt为空会触发jwtAuth.verify报错。
  • 修复代码:
// 增加token存在性校验
const token = req.cookies.jwt;
if (!token) {
  return res.status(401).json('未授权,请先登录');
}
const decoded = jwtAuth.verify(token, process.env.TOKEN_SECRET);
const userId = decoded.id;

// ...

// 给用户查询添加await
const user = await User.findByPk(userId);
if (!user) return res.status(404).json('User not found');

2. 异步操作未等待导致数据不一致

  • 问题:post.update是异步操作但未用await,可能出现点赞记录创建后,帖子点赞数未更新就返回响应;Like.findOrCreate的返回值是[instance, created],原判断逻辑不准确。
  • 修复代码:
// 替换原findOrCreate的then回调逻辑
const [likeInstance, created] = await Like.findOrCreate({
  where: { userId, postId }
});

if (created) {
  await post.update({
    likes: post.likes + 1
  });
  // 返回更新后的关键数据,方便前端同步Store
  return res.status(201).json({
    message: 'Vous avez aimé cette publication.',
    userId: userId,
    likesCount: post.likes + 1
  });
} else {
  return res.status(409).json("Post already liked!");
}

3. 取消点赞接口的冗余操作

  • 问题:未找到点赞记录时,执行post.update({likes: post.likes})无意义,直接返回错误即可。
  • 修复代码:
await Like.destroy({ where: { userId, postId } })
.then(async (deletedCount) => {
  if (deletedCount === 0) {
    return res.status(409).json("Vous avez déjà disliker ce post.");
  } else {
    await post.update({
      likes: post.likes - 1
    });
    return res.status(200).json({
      message: "Vous n'aimez plus ce post.",
      userId: userId,
      likesCount: post.likes - 1
    });
  }
})

前端问题修复

1. Axios请求未携带Cookie

  • 问题:后端从Cookie获取token,但前端跨域请求默认不携带Cookie,导致后端无法验证身份。
  • 修复代码:
export const likePost = (postId) => {
  return (dispatch) => {
    return axios({
      method: 'patch',
      url: `${process.env.REACT_APP_API_URL}api/post/${postId}/like-post`,
      withCredentials: true // 新增:允许携带跨域Cookie
    })
    .then((res) => {
      dispatch({ 
        type: LIKE_POST, 
        payload: { 
          postId, 
          userId: res.data.userId,
          likesCount: res.data.likesCount 
        } 
      })
    })
    .catch((err) => console.log(err))
  }
}

2. Reducer更新逻辑错误

  • 问题:原Reducer将likers直接设置为action.payload,但action.payload是包含postId的对象,并非用户列表。
  • 修复代码:
case LIKE_POST:
  return state.map((post) => {
    if (post.id === action.payload.postId) {
      return {
        ...post,
        likes: action.payload.likesCount,
        likers: [...post.likers, { id: action.payload.userId }] // 将当前用户添加到点赞列表
      };
    }
    return post;
  });

3. LikeButton组件的无限循环与状态同步问题

  • 问题:useEffect依赖isLiked导致无限循环;手动setIsLiked(true)会与Redux Store状态不同步。
  • 修复代码:
const LikeButton = ({ post }) => {
  const [isLiked, setIsLiked] = useState(false);
  const uid = useContext(UidContext);
  const dispatch = useDispatch();

  const handleLike = () => {
    dispatch(likePost(post.id));
  };

  const handleUnLike = () => {
    dispatch(dislikePost(post.id)); // 需实现对应的取消点赞Action
  };

  useEffect(() => {
    // 从Redux Store的post数据中判断是否已点赞
    const hasLiked = post.likers.some(like => like.id === uid);
    setIsLiked(hasLiked);
  }, [uid, post.likers]); // 移除isLiked依赖,避免无限循环

  return (
    <>
      {!isLiked && (
        <>
          <span onClick={handleLike} className="card__like__heart__light"></span>
          <span className="card__like__length">
            {post.likers?.length || 0} Like
          </span>
        </>
      )}
      {isLiked && (
        <>
          <span onClick={handleUnLike} className="card__like__heart__full"></span>
          <span className="card__like__length liked">
            {post.likers?.length || 0} Like
          </span>
        </>
      )}
    </>
  );
};

4. 补充取消点赞Action与Reducer处理

  • 取消点赞Action代码:
export const dislikePost = (postId) => {
  return (dispatch) => {
    return axios({
      method: 'patch',
      url: `${process.env.REACT_APP_API_URL}api/post/${postId}/dislike-post`,
      withCredentials: true
    })
    .then((res) => {
      dispatch({ 
        type: DISLIKE_POST, 
        payload: { 
          postId, 
          userId: res.data.userId,
          likesCount: res.data.likesCount 
        } 
      })
    })
    .catch((err) => console.log(err))
  }
}
  • Reducer中添加取消点赞处理:
case DISLIKE_POST:
  return state.map((post) => {
    if (post.id === action.payload.postId) {
      return {
        ...post,
        likes: action.payload.likesCount,
        likers: post.likers.filter(like => like.id !== action.payload.userId) // 移除当前用户的点赞记录
      };
    }
    return post;
  });

内容的提问来源于stack exchange,提问作者Oumar MAURET

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 11:48:59