点赞系统数据错误存入其他用户数组问题求助
点赞系统数据存储错误的解决方案
问题根源
- 后端查询条件错误:
findOneAndUpdate的第一个参数需要是查询对象,直接传secret字符串会被MongoDB当作{_id: secret}处理,导致更新了错误的用户文档。 - 前端API调用参数混淆:点赞时的接口参数搞反了,没有正确指定要更新的目标用户(登录用户Bob)和被点赞用户(John)。
- 其他细节问题:前端
fetchUsers中filter结果未赋值,导致allUsers包含当前登录用户;post函数重复调用产生多余请求;异步操作未按顺序执行可能导致请求中断。
修正后的代码
后端(mainController)
updateLikes: async (req, res) => { const { secret } = req.params; const likesObj = req.body; // 正确通过secret字段匹配目标用户 const updateUser = await UserSchema.findOneAndUpdate( { secret: secret }, { $push: { likes: likesObj } }, { returnDocument: 'after' } ); console.log('更新likes的用户secret:', secret); // findOneAndUpdate已完成持久化,无需重复调用save() return res.send({ error: false, message: 'Likes updated!', data: null }); }, updateLiked: async (req, res) => { const { secret } = req.params; const likedObj = req.body; // 正确通过secret字段匹配目标用户 const updateLiked = await UserSchema.findOneAndUpdate( { secret: secret }, { $push: { liked: likedObj } }, { returnDocument: 'after' } ); console.log('更新liked的用户secret:', secret); return res.send({ error: false, message: 'Liked updated!', data: null }); },
前端(TestPage组件)
import React, { useState, useEffect } from 'react'; import { Link, useParams, useNavigate } from 'react-router-dom'; import Toolbar from '../components/Toolbar'; import { get, post } from '../helper/helper'; export default function TestPage() { const [current, setCurrent] = useState(); const [index, setIndex] = useState(0); const [allUsers, getAllUsers] = useState([]); const localSecret = window.localStorage.getItem('secret'); const nav = useNavigate(); const { user } = useParams(); useEffect(() => { async function currentUser() { const resp = await get(`user/${localSecret}`); setCurrent(resp.data); } currentUser(); }, [localSecret]); useEffect(() => { async function fetchUsers() { const resp = await get('api'); // 过滤掉当前登录用户,避免自己点赞自己 const filteredUsers = resp.filter(user => user.secret !== localSecret); getAllUsers(filteredUsers); } fetchUsers(); }, [localSecret]); const currentUser = allUsers[index]; // 给被点赞用户的likes数组添加当前登录用户信息 async function postLikes() { await post(current, `likes/${currentUser.secret}`); } // 给当前登录用户的liked数组添加被点赞用户信息 async function postLiked() { await post(currentUser, `liked/${localSecret}`); } async function postDislike() { await post(currentUser, `dislike/${localSecret}`); } // 统一处理点赞逻辑,确保异步请求完成后再执行页面跳转 const handleLike = async () => { await Promise.all([postLiked(), postLikes()]); setIndex(index + 1); nav(`/${currentUser.secret}`); }; const handleDislike = async () => { await postDislike(); setIndex(index + 1); nav(`/${currentUser.secret}`); }; if (!currentUser) return <div>加载中...</div>; return ( <div className='home__page'> <Toolbar /> <div className="home__users"> <div className='single__user'> <img src={currentUser.image[0]} alt={`${currentUser.firstName} ${currentUser.lastName}`} /> <h3>{`${currentUser.firstName} ${currentUser.lastName}`}</h3> <h4>{currentUser.gender}</h4> <button onClick={handleDislike}>Dislike</button> <button onClick={handleLike}>Like</button> </div> </div> <footer className='footer'> <p>All rights reserved by Cartoon Match organization. To read more about our policy <Link to='/policy'>click here</Link>. </p> </footer> </div> ); }
关键修正说明
- 后端查询逻辑:将
findOneAndUpdate(secret, ...)改为findOneAndUpdate({ secret: secret }, ...),精准匹配目标用户文档。 - 前端接口调用:
postLikes:给被点赞用户(currentUser)的likes数组添加登录用户信息,接口路径使用currentUser.secret。postLiked:给登录用户(localSecret)的liked数组添加被点赞用户信息,接口路径使用localSecret。
- 异步操作优化:用
Promise.all确保两个点赞相关请求完成后再执行页面跳转和索引更新,避免请求中断。 - 用户列表过滤:正确保存
filter结果,排除当前登录用户,避免无效交互。 - 移除冗余操作:删除
findOneAndUpdate后的save()调用,避免重复持久化。
内容的提问来源于stack exchange,提问作者Paulius
相关产品推荐
相关产品推荐

