React数据/状态变更是否重绘所有UI?如何仅更新内容样式避免重绘
解决方案
1. 合并单个节点结构,保证DOM可复用
你现有代码根据条件返回多个结构完全一致仅属性不同的<button>节点,会增加React diff的开销,直接合并为单个节点,仅动态计算样式和内容即可,保证React可以100%复用现有DOM节点,不会触发节点重建:
// Circle组件内先计算样式和内容 const getBtnStyle = (id) => { let backgroundColor = "grey" if(dataC[id] === 1) backgroundColor = "green" else if(dataC[id] === 2) backgroundColor = "yellow" else if(spike[id] === 3) backgroundColor = "cyan" else backgroundColor = "purple" return { backgroundColor, padding: pad } } const getBtnContent = (id) => { // 按你的业务逻辑返回对应内容即可 return 你的判断条件 ? id : count } // 渲染时仅返回单个button结构 return ( <div className="show-data" onWheel={onWheelHandler}> {dataS.map((item, id) => ( <button className="wave-circle" style={getBtnStyle(id)} key={id} > {getBtnContent(id)} </button> ))} </div> )
2. 抽离单个Circle为独立记忆化组件,避免全量重渲染
把循环的单个按钮抽成用React.memo包裹的纯组件,仅当对应项的依赖数据变化时才会重渲染,其余项完全不更新:
// 抽离的独立组件,仅props变化时才重渲染 const CircleItem = React.memo(({ id, dataCVal, spikeVal, count, pad }) => { // 用useMemo缓存计算结果,进一步减少不必要的计算 const btnStyle = React.useMemo(() => { let backgroundColor = "grey" if(dataCVal === 1) backgroundColor = "green" else if(dataCVal === 2) backgroundColor = "yellow" else if(spikeVal === 3) backgroundColor = "cyan" else backgroundColor = "purple" return { backgroundColor, padding: pad } }, [dataCVal, spikeVal, pad]) const content = React.useMemo(() => { // 你的业务逻辑判断 return 条件 ? id : count }, [id, count]) return <button className="wave-circle" style={btnStyle}>{content}</button> }) // 原Circle组件内直接调用抽离的组件 return ( <div className="show-data" onWheel={onWheelHandler}> {dataS.map((item, id) => ( <CircleItem key={id} id={id} dataCVal={dataC[id]} spikeVal={spike[id]} count={count} pad={pad} /> ))} </div> )
因为传入CircleItem的props都是基本类型,只要对应位置的数值没有变化,该组件就不会重渲染,也不会触发任何DOM操作。
3. 优化父组件传参逻辑
- 如果你每次接收到socket数据后都是直接生成全新的
dataS、dataC数组,不需要修改这个逻辑,抽离子组件的方案不受数组引用变化的影响 - 可以用
React.memo包裹整个Circle组件,避免父组件其他无关状态变化导致Circle组件不必要的重渲染 - 因为你的数组长度固定为10000,不会有增删操作,用索引作为
key是完全合理的,不需要修改key的取值
4. 可选极端优化:虚拟滚动
10000个节点全量渲染本身会占用大量内存,如果你不需要同时展示所有节点,可以用虚拟滚动方案只渲染可视区域内的几十到上百个节点,更新性能会提升几十到上百倍。
内容的提问来源于stack exchange,提问作者user16972560
相关产品推荐
相关产品推荐

