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

Material UI中Select切换导致卡片网格全量重渲染的问题排查

问题原因

每次切换Select组件时,target状态更新会触发父组件Page重渲染,而handleButtonClick函数会在每次重渲染时被重新创建。由于每个GridCard都接收这个新函数作为props,React会判定卡片的props发生了变化,进而触发所有卡片的重渲染,导致网格整体渲染变慢。

修复方案

1. 用useCallback缓存点击事件函数

通过useCallback将handleButtonClick缓存起来,只有当依赖的target状态变化时,才重新生成这个函数,避免父组件每次重渲染都创建新的函数实例。

2. 用React.memo优化GridCard组件

React.memo会对组件的props进行浅比较,只有当props真正发生变化时,才会重新渲染组件,以此避免不必要的重渲染。

修改后的代码示例

Page.js

import { useState, useCallback } from 'react';

export default function Page() {
  const [target, setTarget] = useState('');

  // 使用useCallback缓存函数,依赖项为target
  const handleButtonClick = useCallback((cardName) => {
    console.log(`${target} was the target of ${cardName}`);
  }, [target]);
  
  return(
    <div>
      <TargetSelect setTarget={setTarget} />
      <Grid>
        <GridCard cardName="Card 1" handleButtonClick={handleButtonClick} />
        <GridCard cardName="Card 2" handleButtonClick={handleButtonClick} />
        <GridCard cardName="Card 3" handleButtonClick={handleButtonClick} />
        <GridCard cardName="Card 4" handleButtonClick={handleButtonClick} />
      </Grid>
    </div>
  )
}

GridCard.js

import { memo } from 'react';

// 用React.memo包裹组件
const GridCard = memo(({ cardName, handleButtonClick }) => {
  return (
    <div className="card">
      <h3>{cardName}</h3>
      <button onClick={() => handleButtonClick(cardName)}>点击</button>
    </div>
  );
});

export default GridCard;
补充说明

如果GridCard的props包含嵌套对象这类复杂数据,浅比较可能无法准确识别实际变化,这时可以给memo传入第二个参数,自定义props的比较逻辑。但针对当前场景,浅比较已经足够解决重渲染问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 03:40:29