欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 如何在 React 项目中优化列表渲染性能,避免不必要的重绘?

如何在 React 项目中优化列表渲染性能,避免不必要的重绘?

2025/3/25 23:31:14 来源:https://blog.csdn.net/qq_37212162/article/details/146428156  浏览:    关键词:如何在 React 项目中优化列表渲染性能,避免不必要的重绘?

大白话如何在 React 项目中优化列表渲染性能,避免不必要的重绘?

在 React 项目里,要是列表数据量很大,每次数据变化都重新渲染列表,会严重影响性能。

1. 使用 key 属性

key 属性能帮助 React 识别哪些元素发生了变化,这样在更新列表时,React 就只更新那些真正改变的元素,而不是重新渲染整个列表。

import React from 'react';// 假设这是我们的数据列表
const data = [{ id: 1, name: 'Alice' },{ id: 2, name: 'Bob' },{ id: 3, name: 'Charlie' },
];const ListComponent = () => {return (<ul>{/* 遍历数据列表,为每个列表项添加唯一的 key */}{data.map(item => (<li key={item.id}>{item.name}</li>))}</ul>);
};export default ListComponent;

在这个例子中,key 属性被设置为 item.id,因为 id 是唯一的,这样 React 就能准确知道哪些元素改变了。

2. 使用 React.memo 进行组件缓存

React.memo 是一个高阶组件,它能对组件进行浅比较,如果组件的 props 没有变化,就不会重新渲染。

import React from 'react';// 定义一个简单的列表项组件
const ListItem = React.memo(({ item }) => {// 这里返回列表项的 JSXreturn <li>{item.name}</li>;
});// 假设这是我们的数据列表
const data = [{ id: 1, name: 'Alice' },{ id: 2, name: 'Bob' },{ id: 3, name: 'Charlie' },
];const ListComponent = () => {return (<ul>{/* 遍历数据列表,使用 ListItem 组件 */}{data.map(item => (<ListItem key={item.id} item={item} />))}</ul>);
};export default ListComponent;

在这个例子中,ListItem 组件被 React.memo 包裹,当 item props 没有变化时,这个组件就不会重新渲染。

3. 使用 shouldComponentUpdate(类组件)

在类组件中,可以使用 shouldComponentUpdate 生命周期方法来控制组件是否需要重新渲染。

import React from 'react';// 定义一个类组件作为列表项
class ListItem extends React.Component {// shouldComponentUpdate 方法,用于控制组件是否重新渲染shouldComponentUpdate(nextProps) {// 比较当前 props 和下一个 props 的 item 是否相同return this.props.item.name !== nextProps.item.name;}render() {// 这里返回列表项的 JSXreturn <li>{this.props.item.name}</li>;}
}// 假设这是我们的数据列表
const data = [{ id: 1, name: 'Alice' },{ id: 2, name: 'Bob' },{ id: 3, name: 'Charlie' },
];const ListComponent = () => {return (<ul>{/* 遍历数据列表,使用 ListItem 组件 */}{data.map(item => (<ListItem key={item.id} item={item} />))}</ul>);
};export default ListComponent;

在这个例子中,shouldComponentUpdate 方法会比较当前的 item props 和下一个 item props 是否相同,如果相同就不重新渲染组件。

4. 虚拟列表

当列表数据量非常大时,可以使用虚拟列表只渲染用户可见区域的列表项,从而提高性能。下面是一个简单的虚拟列表示例:

import React, { useState } from 'react';// 假设这是我们的大数据列表
const bigData = Array.from({ length: 1000 }, (_, i) => ({ id: i, name: `Item ${i}` }));const VirtualList = () => {// 定义每个列表项的高度const itemHeight = 30;// 定义容器的高度const containerHeight = 300;// 定义显示的列表项数量const visibleItemCount = Math.floor(containerHeight / itemHeight);// 使用 useState 来管理滚动偏移量const [scrollOffset, setScrollOffset] = useState(0);// 计算开始索引const startIndex = Math.floor(scrollOffset / itemHeight);// 计算结束索引const endIndex = startIndex + visibleItemCount;// 截取可见区域的数据const visibleData = bigData.slice(startIndex, endIndex);return (<divstyle={{ height: containerHeight, overflowY: 'auto' }}onScroll={(e) => setScrollOffset(e.target.scrollTop)}>{/* 为不可见区域预留高度 */}<div style={{ height: startIndex * itemHeight }} />{/* 渲染可见区域的列表项 */}{visibleData.map(item => (<div key={item.id} style={{ height: itemHeight }}>{item.name}</div>))}{/* 为不可见区域预留高度 */}<div style={{ height: (bigData.length - endIndex) * itemHeight }} /></div>);
};export default VirtualList;

在这个例子中,VirtualList 组件只渲染用户可见区域的列表项,当用户滚动时,动态更新可见区域的数据,这样可以显著提高性能。

通过以上这些方法,就能在 React 项目中优化列表渲染性能,避免不必要的重绘。

除了使用 key 属性,还有哪些方法可以优化 React 列表渲染性能?

在 React 里,除了使用 key 属性,还有不少方法可以优化列表渲染性能,下面详细介绍:

1. 使用 React.memo 进行组件缓存

React.memo 是一个高阶组件,它可以对函数组件进行浅比较,若组件的 props 没有变化,就不会重新渲染该组件。

import React from 'react';// 使用 React.memo 包裹组件,对传入的 props 进行浅比较
const ListItem = React.memo(({ item }) => {// 渲染列表项return <li>{item.name}</li>;
});const data = [{ id: 1, name: 'Alice' },{ id: 2, name: 'Bob' },{ id: 3, name: 'Charlie' }
];const ListComponent = () => {return (<ul>{/* 遍历数据数组,渲染列表项 */}{data.map(item => (<ListItem key={item.id} item={item} />))}</ul>);
};export default ListComponent;

在上述代码中,ListItem 组件被 React.memo 包裹。当 item 属性没有改变时,ListItem 组件不会重新渲染,以此减少不必要的渲染。

2. 类组件使用 shouldComponentUpdate

在类组件里,shouldComponentUpdate 生命周期方法能够控制组件是否重新渲染。你可以在这个方法里比较 propsstate,依据比较结果决定是否重新渲染。

import React from 'react';class ListItem extends React.Component {// shouldComponentUpdate 方法,用于决定组件是否重新渲染shouldComponentUpdate(nextProps) {// 比较当前和下一个 props 的 item 属性return this.props.item.name!== nextProps.item.name;}render() {// 渲染列表项return <li>{this.props.item.name}</li>;}
}const data = [{ id: 1, name: 'Alice' },{ id: 2, name: 'Bob' },{ id: 3, name: 'Charlie' }
];const ListComponent = () => {return (<ul>{/* 遍历数据数组,渲染列表项 */}{data.map(item => (<ListItem key={item.id} item={item} />))}</ul>);
};export default ListComponent;

在这个例子中,shouldComponentUpdate 方法会比较当前 props 和下一个 propsitem.name 是否相同,若相同则不重新渲染组件。

3. 使用 PureComponent

React.PureComponentReact.Component 类似,但它自动实现了 shouldComponentUpdate 方法,会对 propsstate 进行浅比较。

import React from 'react';// 继承 React.PureComponent
class ListItem extends React.PureComponent {render() {// 渲染列表项return <li>{this.props.item.name}</li>;}
}const data = [{ id: 1, name: 'Alice' },{ id: 2, name: 'Bob' },{ id: 3, name: 'Charlie' }
];const ListComponent = () => {return (<ul>{/* 遍历数据数组,渲染列表项 */}{data.map(item => (<ListItem key={item.id} item={item} />))}</ul>);
};export default ListComponent;

在上述代码中,ListItem 组件继承自 React.PureComponent,当 propsstate 发生浅层次的变化时,组件才会重新渲染。

4. 虚拟列表

当列表数据量非常大时,可采用虚拟列表技术,只渲染用户可见区域的列表项。

import React, { useState } from 'react';// 模拟大量数据
const bigData = Array.from({ length: 1000 }, (_, i) => ({ id: i, name: `Item ${i}` }));const VirtualList = () => {// 每个列表项的高度const itemHeight = 30;// 容器的高度const containerHeight = 300;// 可见列表项的数量const visibleItemCount = Math.floor(containerHeight / itemHeight);// 滚动偏移量状态const [scrollOffset, setScrollOffset] = useState(0);// 计算开始索引const startIndex = Math.floor(scrollOffset / itemHeight);// 计算结束索引const endIndex = startIndex + visibleItemCount;// 获取可见区域的数据const visibleData = bigData.slice(startIndex, endIndex);return (<divstyle={{ height: containerHeight, overflowY: 'auto' }}onScroll={(e) => setScrollOffset(e.target.scrollTop)}>{/* 为不可见区域预留高度 */}<div style={{ height: startIndex * itemHeight }} />{/* 渲染可见区域的列表项 */}{visibleData.map(item => (<div key={item.id} style={{ height: itemHeight }}>{item.name}</div>))}{/* 为不可见区域预留高度 */}<div style={{ height: (bigData.length - endIndex) * itemHeight }} /></div>);
};export default VirtualList;    

在这个例子中,VirtualList 组件仅渲染用户可见区域的列表项,当用户滚动时,动态更新可见区域的数据,避免了渲染大量不可见的列表项,从而提升了性能。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词