我们什么时候应该担心函数组件重新定义变量和函数?
我认为第一种情况显然是不必要的,创建函数并不昂贵(并且反应开发工具配置文件测试没有检测到 useCallback 的性能变化)
import React, { useState, useMemo, useCallback } from "react";
export const App = () => {
const [counter, setCounter] = useState(1);
const showCounter = useCallback(() => {
console.log(counter);
}, [counter]);
return (
<>
<button onClick={showCounter}>Show</button>
<button onClick={() => setCounter(counter + 1)}>Add</button>
</>
);
};
另一方面,在另一个示例中,使用 react 开发工具,我们可以检测到 useMemo 将渲染时间缩短了一半:
import React, { useState, useMemo, useCallback } from "react";
export const App = () => {
const [counter, setCounter] = useState(1);
const [list, setList] = useState<number[]>([]);
function setListItem(item: number) {
setList([...list, item]);
}
//should we useMemo here?
const domList = useMemo(
() =>
list.map((value: number, index: number) => (
<li key={index}> {value} </li>
)),
[list]
);
return (
<>
<p>{counter}</p>
<button onClick={() => setCounter(counter - 1)}>Subtract</button>
<button onClick={() => setCounter(counter + 1)}>Add</button>
<button onClick={() => setListItem(counter)}>Push to array</button>
<h1>List</h1>
<ul>{domList}</ul>
</>
);
};
但是当我们谈论前端时,仍然不到一毫秒的增益和数组映射和 JSX 数组也不是什么真正昂贵的东西。然而,在每次渲染中运行一个数组映射方法是非常不舒服的。那么,这些事情我们应该怎么做呢?(让我们忘记什么时候我们有 useEffect 依赖于一些使 useMemo 成为必要的变量)
- 所有不需要在每次渲染中重新定义的函数和变量中的 useCallback 和 useMemo。
- useCallback 和 useMemo 仅用于我们可以清楚地看到性能提升的事情(即使大多数时间都不能算作对 UX 的改进)。所以在第二个例子中我们需要 useMemo。
- 仅当在特定情况下不使用 useCallback 和 useMemo 时,我们会得到很大的用户体验下降。所以只有真正昂贵的函数才会使用回调