思路
- 使用 React.memo 包裹列表组件:React.memo 是一个高阶组件,它可以对函数式组件进行浅比较,只有当 props 发生变化时才会重新渲染组件,避免不必要的渲染。
- 合理使用 useState 和 useEffect:在状态更新时,确保只在必要时触发重新渲染。例如,对于搜索和排序的状态,只在相关值改变时才重新计算过滤和排序后的列表。
- 防抖(Debounce)处理搜索输入:当用户输入搜索内容时,频繁触发搜索操作会导致性能问题。使用防抖可以在用户停止输入一段时间后再执行搜索,减少不必要的计算。
关键代码片段
import React, { useState, useEffect, memo } from 'react';
// 模拟数据
const dataList = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 20 }
];
// 列表组件,使用 React.memo 优化
const ListItem = memo(({ item }) => {
return (
<li>
Name: {item.name}, Age: {item.age}
</li>
);
});
const App = () => {
const [searchText, setSearchText] = useState('');
const [sortByAge, setSortByAge] = useState(false);
const [filteredList, setFilteredList] = useState(dataList);
// 防抖函数
const debounce = (func, delay) => {
let timer;
return function() {
const context = this;
const args = arguments;
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(context, args);
}, delay);
};
};
const handleSearch = debounce((text) => {
setSearchText(text);
const newFilteredList = dataList.filter(item =>
item.name.toLowerCase().includes(text.toLowerCase())
);
setFilteredList(newFilteredList);
}, 300);
useEffect(() => {
if (sortByAge) {
const sortedList = filteredList.sort((a, b) => a.age - b.age);
setFilteredList(sortedList);
} else {
const newFilteredList = dataList.filter(item =>
item.name.toLowerCase().includes(searchText.toLowerCase())
);
setFilteredList(newFilteredList);
}
}, [sortByAge, searchText]);
return (
<div>
<input
type="text"
placeholder="Search by name"
onChange={(e) => handleSearch(e.target.value)}
/>
<button onClick={() => setSortByAge(!sortByAge)}>
{sortByAge? 'Cancel Sort by Age' : 'Sort by Age'}
</button>
<ul>
{filteredList.map((item, index) => (
<ListItem key={index} item={item} />
))}
</ul>
</div>
);
};
export default App;