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

点赞系统数据错误存入其他用户数组问题求助

点赞系统数据存储错误的解决方案

问题根源

  1. 后端查询条件错误:findOneAndUpdate的第一个参数需要是查询对象,直接传secret字符串会被MongoDB当作{_id: secret}处理,导致更新了错误的用户文档。
  2. 前端API调用参数混淆:点赞时的接口参数搞反了,没有正确指定要更新的目标用户(登录用户Bob)和被点赞用户(John)。
  3. 其他细节问题:前端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>
    );
}

关键修正说明

  1. 后端查询逻辑:将findOneAndUpdate(secret, ...)改为findOneAndUpdate({ secret: secret }, ...),精准匹配目标用户文档。
  2. 前端接口调用:
    • postLikes:给被点赞用户(currentUser)的likes数组添加登录用户信息,接口路径使用currentUser.secret。
    • postLiked:给登录用户(localSecret)的liked数组添加被点赞用户信息,接口路径使用localSecret。
  3. 异步操作优化:用Promise.all确保两个点赞相关请求完成后再执行页面跳转和索引更新,避免请求中断。
  4. 用户列表过滤:正确保存filter结果,排除当前登录用户,避免无效交互。
  5. 移除冗余操作:删除findOneAndUpdate后的save()调用,避免重复持久化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:30:16