在传递回调函数时,尤其是在传递参数化函数时,我知道我应该使用useCallback
钩子,因为使用匿名函数可能会对性能产生不利影响。
我说的匿名函数示例就是这样。
import React, { useState } from 'react';
const Component = () => {
const [param, setParam] = useState('');
...
return (
...
<SomeComponent
onClick={() => setParam('parameter')}
{...others}
/>
);
}
在将匿名函数转换为使用此挂钩的过程中,我遇到了一个错误消息,提示“渲染太多”或它无法正常工作。 但是我不知道在什么情况下以及什么情况下。
我像下面一样使用useCallback
。
import React, { useState, useCallback } from 'react';
const Component = () => {
const [param, setParam] = useState('');
const handleClick = useCallback((params) => {
setParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
);
}
但是,当使用匿名函数在useCallback
中返回时,它也起作用。
这意味着像这里的代码。 (仅与上面的代码相比有所不同。)
const handleClick = useCallback((params) => {
return () => setParam(params);
},[]);
在这种情况下,如果我只是使用匿名函数而不是使用此钩子,我想知道是否比仅在useCallback
内部使用匿名函数更糟糕。
答案 0 :(得分:2)
const handleClick = useCallback((params) => {
setParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
);
在上面的代码中,在第一次渲染期间的处,此语句"onClick={handleClick('parameter')}"
的handleClick函数使用名为“ parameter”的字符串进行调用。由于handleClick具有setParam(“ parameter”),它将更新状态。更新状态将导致重新渲染,并再次出现在同一语句"onClick={handleClick('parameter')}"
中,从而导致无限循环。
后面添加的以下代码可以正常工作,因为您没有更新状态,而是返回了一个函数,该函数充当onclick处理程序。
const handleClick = useCallback((params) => {
return () => setParam(params);
},[]);
最好的跟随方式是
import React, { useState, useCallback } from 'react';
const Component = () => {
const [param, setParam] = useState('');
const handleClick = useCallback((params) => {
setParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick}
{...others}
/>
);
}
回到您的问题,比较性能取决于其他功能定义以及子组件内部返回函数中的子组件的渲染时间。 假设您的应用中还有一个名为“ anotherHandleClick”的onclickHanldier。 然后您的组件看起来像这样
const Component = () => {
const [param, setParam] = useState('');
const [anotherParam, setAnotherParam] = useState('');
const handleClick = (params) => {
setParam(params);
};
const anotherHandleClick =(params) => {
setAnotherParam(params);
};
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
<SomeComponent
onClick={antherHandleClick('parameter')}
{...others}
/>
);
}
在上面的组件中,当“ SomeCompoenent”中的任何一个都单击时重新进入“ Component”,因此将重新定义处理程序函数。当两者都对onclick处理程序函数进行参照相等性检查时,他们认为这是新的处理函数,要求它们同时渲染两者。 在这种情况下,最好使用useCallBack挂钩,如下所示,
const Component = () => {
const [param, setParam] = useState('');
const [anotherParam, setAnotherParam] = useState('');
const handleClick = useCallback((params) => {
setParam(params);
},[]);
const anotherHandleClick = useCallback((params) => {
setAnotherParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
<SomeComponent
onClick={antherHandleClick('parameter')}
{...others}
/>
);
}
在上面的代码中,当单击任何一个时,状态都会改变。然后在呈现时,useCallback确保onclick处理程序的引用没有更改。因此,依赖于onclick处理程序的依赖关系不会重新呈现。
所以最终的想法是 在两种情况下,它都会在每个渲染器上创建一个函数。第二个(因为它包装在useCallback中)将返回在初始渲染器上创建的备注函数
何时使用useMemo或useCallback refer this
答案 1 :(得分:0)
在您的代码中:
react-datepicker__header
您应该像这样将参数传递到const handleClick = useCallback((params) => {
setParam(params);
},[]);
的第二个参数中:
useCallback
答案 2 :(得分:0)
useCallback钩子用法会更好。因为挂钩记得内部功能,所以它可以提供更好的性能。