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
相关产品推荐
相关产品推荐

