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

Next.js中React.memo未生效 组件重复渲染areEqual未调用问题

问题根因

你观察到的异常现象来自三个核心认知偏差和代码错误:

  • 对React.memo的作用范围理解错误:React.memo仅针对 同一个组件实例 做重渲染优化,当父组件重渲染时,会对比该实例前后的props,决定是否跳过该实例的本次重渲染。它不会在多个独立的组件实例之间共享渲染结果。你在页面中编写了3个独立的<DynamicTest msg="test" />,属于3个完全独立的组件实例,每个实例首次挂载时都会独立执行组件逻辑、生成独立的随机数,三个实例输出不同随机值是完全符合React运行逻辑的正常表现。
  • 对自定义比较函数areEqual的触发时机理解错误:areEqual仅在组件完成首次挂载、后续因父组件更新触发子组件更新检查时才会执行,首次挂载阶段不会调用该函数。你当前看到的所有渲染日志,都是三个组件实例首次挂载时的输出,根本没有走到更新对比流程,自然看不到areEqual的打印日志。
  • areEqual的对比逻辑编写错误:你当前写的return prevProps === nextProps是对比两个props对象的引用地址。React每次渲染传递给子组件的props都是新创建的普通对象,即便对象内所有属性值完全一致,两个对象的引用地址也不相同,这个判断会永远返回false,相当于完全失效,后续父组件重渲染时子组件依然会无条件重渲染。
  • 额外干扰项:Next.js开发环境默认开启React 18严格模式,会在开发阶段对组件执行两次挂载-卸载的模拟流程,用来检测不符合规范的副作用代码,会导致开发环境的渲染日志比生产环境多一倍,这个行为仅在开发环境存在,生产构建后会自动关闭。
修复与验证方式
  1. 首先修正areEqual的对比逻辑,不要直接对比props对象引用,而是对比组件实际依赖的属性值:
// /components/test.tsx
import React from "react";

type TestProps = {
  msg: string;
};

function areEqual(prevProps: TestProps, nextProps: TestProps) {
  return prevProps.msg === nextProps.msg;
}

export default React.memo<TestProps>(({ msg }) => {
  console.log("Test rendered");
  const txt = `${msg}${Math.random()}`;
  return <div>Test: {txt}</div>;
}, areEqual);
  1. 要正确验证React.memo的生效逻辑,你需要触发父组件重渲染,观察同一个Test实例是否会跳过不必要的重渲染,而不是观察多个独立实例的首次挂载输出。可以给页面增加一个计数状态做测试:
// /pages/index.tsx
import React, { useState } from "react";
import Link from "next/link";
import dynamic from "next/dynamic";

const DynamicTest = dynamic(() => import("../components/test"), { ssr: false });

export default () => {
  const [count, setCount] = useState(0);
  return (
    <div>
      <DynamicTest msg="test" />
      <button onClick={() => setCount(c => c + 1)}>触发父组件重渲染,当前计数:{count}</button>
      <Link href="/second">
        <a>跳转到第二个页面</a>
      </Link>
    </div>
  );
};

修正后点击按钮触发父组件重渲染时,areEqual会被正常调用,由于传入的msg属性没有变化,Test组件不会重复执行渲染逻辑,控制台不会重复打印Test rendered日志,组件内展示的随机值也不会发生变化,这才是React.memo生效的正确表现。

补充说明:如果你关闭React严格模式,组件首次挂载的渲染日志会减少一半,但三个独立实例输出不同随机值的表现不会改变,这不属于bug。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:24:17