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
相关产品推荐
相关产品推荐

