这里是一个带有点击处理程序的 2 个按钮的示例,一个函数在组件主体中创建,另一个在 JSX 中创建。有性能差异吗?
function Parent() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<button onClick={handleClick} />
<button onClick={() => setCount(count + 1)}>Increment Count</button>
</div>
);
}
我的理解是它们是相同的,并且函数会在每次
Parent
重新渲染时重新创建。但我很好奇我是否遗漏了什么。我知道我可以使用useCallback
或其他记忆技术,但这个问题纯粹是这两种情况。
如果有任何性能差异,那也是微不足道的。唯一的区别在于是否将函数分配给中间变量。单个任务非常非常快。另外,在你转译代码、缩小代码,然后浏览器进行自己的优化之后,这个分配有可能根本不存在。
我强烈建议您不要尝试在此级别进行优化。编写代码以提高可读性,并为更大规模的事物保留性能改进。
我知道我可以使用 useCallback 或其他记忆技术
我知道这些不是问题,但我怀疑你可能误解了他们的作用。如果您将函数包装在
useCallback
中,那么您所展示的示例会稍微变慢,而不是更快:
const handleClick = useCallback(() => {
setCount(count + 1);
}, [])
使用这段代码,您仍然会在每次渲染时创建一个函数,因此您已经受到性能的束缚。该函数不会立即分配给 handleClick
,而是传递给
useCallback
,它将迭代依赖项数组进行比较。函数调用加上比较循环非常快,但比什么都不做要慢。
useCallback
具有性能优势,但在您的示例中不存在。当您将函数传递给另一段代码时,好处就来了。如果您每次传递不同的函数,那么其他代码可能需要重复一些工作。例如,一个组件认为它的 props 发生了变化,所以它必须重新渲染;或者
useEffect
认为其依赖项数组已更改,因此必须重新运行。
useCallback
让您每次传递相同的函数,可能会跳过一些工作。