我听说在 react 组件中声明一个函数来处理点击应该在 useCallback 钩子中完成,以避免每次渲染都重新创建函数,特别是如果函数有点复杂,像这样:
const handleClick = useCallback(()=> { "...do a lot of calculations here that takes time" },[]); <button onClick={handleClick}> Click me! </button>
但是我有一个特殊情况,我希望在单击按钮以设置状态时触发 useCallback 函数,这就是我想要的:
const [state, setState] = useState(); const handleClick = useCallback(()=> { const newState = "...do a lot of calculations here that takes time" setState( newState ) },[ when button is clicked ]);
问题是,我如何将“单击按钮时”放在 useCallback 的依赖项上,事实上,任何接受依赖项列表的反应钩子?我可以用一些愚蠢的变量来做到这一点,并将需要时间的昂贵计算与 onClick 函数分开,如下所示,但我认为这不是一个好的方法,因为我会浪费内存:
const [state, setState] = useState(); const [dumb, setDumb] = useState(0); useEffect(()=> { const newState = "...do a lot of calculations here that takes time" setState( newState ) },[ dumb ]); <button onClick=()=>setDumb(dumb+1)> Click me! </button>
我觉得你有点倒退了。useCallback只有当返回的 memoized 函数通过 props 传递给后代组件时,该钩子才真正有用。好处不是函数很重并且优化了一些计算,而是回调引用是稳定的,不会触发子组件的不必要的重新渲染。
useCallback
至于将函数用作按钮的onClick处理程序,它useCallback是传递给按钮处理程序的钩子的返回值,而onClick不是您试图使单击事件成为依赖项的其他方式。
onClick
例子:
const clickHandler = useCallback(() => { // do some expensive computations }, [...dependencies]); ... <button type="button" onClick={clickHander}>Click Me</button>
如果你不clickHandler作为道具传递给另一个 React 组件,那么记忆它并没有太大的好处。
clickHandler
setDumb代码示例是一个使用useEffect钩子更合适的用例,其效果是在更新状态的依赖关系时运行复杂/繁重的代码dumb。
setDumb
useEffect
dumb
将复杂/繁重的逻辑放在常规回调中并在完成时将正常状态更新排入队列更简单。仅使用useCallbackif 将此函数作为道具传递给另一个 React 组件。