我有一个 React 组件,它使用 map 方法呈现大量项目(大约 1000 个)。每个项目都是一个复杂的组件,有自己的状态和属性,并且可以由用户更新。问题是,每当我更新一项时,整个列表都会重新渲染,这会导致明显的滞后和性能问题。我尝试过使用 React.memo 和 useCallback 来防止不必要的重新渲染,但似乎没有太大区别。如何在不影响功能和用户体验的情况下优化 React 中大量项目的渲染?
这是我的代码的简化版本:
// import React and useState hook
import React, { useState } from 'react';
// define a custom component for each item
const Item = ({ item, onUpdate }) => {
// use state to store the item data
const [data, setData] = useState(item);
// handle the change of the input value
const handleChange = (e) => {
// update the data state with the new value
setData({ ...data, value: e.target.value });
};
// handle the click of the update button
const handleClick = () => {
// call the onUpdate prop function with the data state
onUpdate(data);
};
// return the JSX element for the item
return (
<div className="item">
<p>{data.name}</p>
<input type="text" value={data.value} onChange={handleChange} />
<button onClick={handleClick}>Update</button>
</div>
);
};
// define a custom component for the list of items
const List = ({ items }) => {
// use state to store the items data
const [data, setData] = useState(items);
// handle the update of an item
const handleUpdate = (item) => {
// find the index of the item in the data state
const index = data.findIndex((i) => i.id === item.id);
// create a copy of the data state
const newData = [...data];
// replace the item at the index with the updated item
newData[index] = item;
// update the data state with the new data
setData(newData);
};
// return the JSX element for the list of items
return (
<div className="list">
{data.map((item) => (
// use React.memo to memoize each item component and prevent unnecessary re-rendering
React.memo(
// pass the item data and handleUpdate function as props to each item component
<Item key={item.id} item={item} onUpdate={handleUpdate} />
)
))}
</div>
);
};
// define a mock array of items for testing
const mockItems = [
{ id: 1, name: 'Item 1', value: 'Value 1' },
{ id: 2, name: 'Item 2', value: 'Value 2' },
{ id: 3, name: 'Item 3', value: 'Value 3' },
];
// render the list component with the mock items
ReactDOM.render(<List items={mockItems} />, document.getElementById('root'));
如有任何帮助或建议,我们将不胜感激。预先感谢。
看起来差别不大
嗯,差异应该很大,因为您的应用程序应该由于语法错误而崩溃。
React.memo
需要一个React组件,而不是JSX。无论如何,以您的方式使用 React.memo
没有多大意义,因为 memoized 组件(memoized Item
)将随着每个父级(List
)重新渲染而重新创建。
您应该将
Item
包裹在声明位置,改为用 React.memo
代替:
const Item = memo(({ item, onUpdate }) => { ... }));
并用
handleUpdate
包裹 useCallback
。