React的useMemo Hook可以用来优化你的React函数组件的计算成本。我们将先通过一个组件的例子来说明这个问题,然后用React的useMemo Hook来解决这个问题。
请记住,React中的大部分性能优化都是不成熟的。React的默认速度很快,所以每一个性能优化都是选择的,以防某些东西开始感觉到慢。
注意:不要把React的useMemo Hook和React的memo API搞错。useMemo是用来记忆数值的,而React memo是用来包装React组件以防止重新渲染的。
注意:不要把React的useMemo Hook和React的useCallback Hook搞错。useMemo是用来记忆值的,而useCallback是用来记忆函数的。
让我们来看看下面这个React应用程序的例子,它渲染了一个用户列表,并允许我们通过他们的名字来过滤用户。陷阱。只有当用户明确地点击一个按钮时,过滤才会发生;而不是当用户在输入框中输入时才发生。
import React from 'react';
const users = [
{ id: 'a', name: 'Robin' },
{ id: 'b', name: 'Dennis' },
];
const App = () => {
const [text, setText] = React.useState('');
const [search, setSearch] = React.useState('');
const handleText = (event) => {
setText(event.target.value);
};
const handleSearch = () => {
setSearch(text);
};
const filteredUsers = users.filter((user) => {
return user.name.toLowerCase().includes(search.toLowerCase());
});
return (
<div>
<input type="text" value={text} onChange={handleText} />
<button type="button" onClick={handleSearch}>
Search
</button>
<List list={filteredUsers} />
</div>
);
};
const List = ({ list }) => {
return (
<ul>
{list.map((item) => (
<ListItem key={item.id} item={item} />
))}
</ul>
);
};
const ListItem = ({ item }) => {
return <li>{item.name}</li>;
};
export default App;
即使filteredUsers ,当有人在输入框中输入时也不会发生变化,因为它们只在通过search 状态点击按钮时发生变化,过滤器的回调函数在输入框中的每一次击键都会重复运行。
function App() {
...
const filteredUsers = users.filter((user) => {
console.log('Filter function is running ...');
return user.name.toLowerCase().includes(search.toLowerCase());
});
...
}
这并没有减慢这个小型React应用程序的速度。然而,如果我们要处理这个数组中的大量数据,并为每个按键运行过滤器的回调函数,我们也许会拖慢应用程序。因此,你可以使用React的useMemo Hook来记忆一个函数的返回值,并且只在函数的依赖关系(这里是search )发生变化时才运行。
function App() {
...
const filteredUsers = React.useMemo(
() =>
users.filter((user) => {
console.log('Filter function is running ...');
return user.name.toLowerCase().includes(search.toLowerCase());
}),
[search]
);
...
}
现在,这个函数只在search 状态改变时才被执行。如果text 状态发生变化,它就不会运行,因为这不是这个过滤函数的依赖项,因此不是useMemo钩子的依赖项数组中的依赖项。自己试试吧。在输入框中输入一些东西应该不会触发记录,但通过点击按钮执行搜索会触发记录。
毕竟,你可能想知道为什么你不在所有的值计算中使用React的useMemo Hook,或者为什么React的useMemo Hook不是所有值计算的默认值。在内部,React的useMemo Hook必须在每次重新渲染时比较依赖数组中的依赖关系,以决定它是否应该重新计算值。通常情况下,这种比较的计算可能比重新计算数值更昂贵。总之,React的useMemo Hook是用来记忆值的。