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

按点赞量排序分页加载时出现重复Key错误求助

问题描述

我设置了四个筛选器:按最高点赞、最低点赞、最新、最旧排序。测试阶段数据库中答案最多1个点赞、无点赞或1个点踩。选择「最新」或「最旧」筛选时,无限滚动分页正常;但选择「最高点赞」或「最低点赞」时,翻到第2-3页会出现「Encountered two children with the same key, '123456blabla'」错误。

原因分析

核心问题是排序字段的唯一性不足:

  • 按createdAt排序时,每个文档的创建时间都是唯一的,数据库能稳定返回有序结果,分页时不会出现重复数据。
  • 按upvotes排序时,测试数据里大量答案的点赞数相同(都是0、1或-1),此时MongoDB的排序是不稳定的——当排序字段值相同时,MongoDB不会默认按其他字段排序,每次查询的结果顺序可能随机变化。
  • 这就导致分页时,前一页的某些数据会出现在后一页的结果里,当无限滚动把新数据追加到列表时,就出现了重复的_id作为React元素的key,触发重复key错误。
解决办法

给点赞相关的排序规则添加第二排序字段,保证排序的稳定性,比如结合createdAt或MongoDB的唯一_id:

修改服务器端排序逻辑

"use server"

export async function getAnswers(params: GetAnswersParams) {
  try {
    connectToDatabase();

    const { questionId, sortBy, page = 1, pageSize = 5 } = params;

    const skipAmount = (page - 1) * pageSize;

    let sortOptions = {};
    switch (sortBy) {
      case 'highestUpvotes':
        // 先按点赞降序,再按创建时间降序,保证相同点赞数的结果顺序稳定
        sortOptions = { upvotes: -1, createdAt: -1 };
        break;
      case 'lowestUpvotes':
        // 先按点赞升序,再按创建时间升序
        sortOptions = { upvotes: 1, createdAt: 1 };
        break;
      case 'recent':
        sortOptions = { createdAt: -1 };
        break;
      case 'old':
        sortOptions = { createdAt: 1 };
        break;

      default:
        break;
    }

    const answers = await Answer.find({ question: questionId })
      .populate('author', '_id clerkId name picture')
      .sort(sortOptions)
      .skip(skipAmount)
      .limit(pageSize);

    const totalAnswers = await Answer.countDocuments({
      question: questionId,
    });

    const isNext = totalAnswers > skipAmount + answers.length;

    return {
      answers: JSON.parse(JSON.stringify(answers)),
      isNext,
    };
  } catch (error) {
    console.log(error);
    throw error;
  }
}

可选优化

如果不想用createdAt,也可以直接用MongoDB的唯一_id作为第二排序字段,效果更稳定:

// 最高点赞排序
sortOptions = { upvotes: -1, _id: -1 };
// 最低点赞排序
sortOptions = { upvotes: 1, _id: 1 };

这样修改后,相同点赞数的答案每次查询的顺序都会保持一致,分页时不会出现重复数据,React列表的key也就不会重复了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:55:12