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

使用React.memo避免长列表未变更项重渲染的异常问题排查

问题原因

你遇到的异常是点击任意一项的Add按钮后,所有列表项都会触发重渲染,控制台会打印所有id的Rendering -> xxx日志,没有达到仅渲染修改项的优化预期。核心原因有两点:

  • 列表渲染时未添加唯一key属性:React渲染列表时依赖唯一key标识每个组件实例,用来判断哪些实例可以复用、哪些需要更新。未显式指定key时React会默认用索引作为key,每次list状态变更后都会全量重渲染所有列表项。
  • onAdd函数引用不稳定:onAdd定义在App组件内部,每次list状态更新触发App重渲染时,都会生成新的onAdd函数实例,传递给所有Item的onChange属性都是新的。如果后续调整React.memo的比较逻辑为默认浅比较,这个问题仍会触发全量重渲染。
修复方案

按以下步骤修改即可实现仅修改项重渲染:

  1. 给列表项添加唯一key属性,取值为item的id:
{list.map((item) => (
  <Item key={item.id} {...item} onChange={onAdd} />
))}
  1. 用useCallback包裹onAdd函数,同时将setList改为函数式更新,避免依赖外部的list变量,保证onAdd的引用永远稳定:
import React, { useState, useCallback } from "react";

// 省略其他代码
const onAdd = useCallback((id, qtd) => {
  setList(prevList => prevList.map((item) => {
    if (item.id === id) {
      return { ...item, qtd };
    }
    return item;
  }));
}, []);
  1. 完善areEqual比较逻辑,增加id校验避免极端场景下的props错位:
function areEqual(prev, next) {
  return prev.id === next.id && prev.qtd === next.qtd;
}

修改完成后点击任意项的Add按钮,仅当前修改的列表项会触发重渲染,其余未修改项不会产生多余渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 08:54:01