![](/img/trans.png)
[英]Using useEffect on several fetch functions causes them to run before a button click, how do I use useCallback instead?
[英]How to trigger useCallback, useMemo or useEffect on button click?
我听说在一个反应组件中声明一个 function 来处理点击应该在 useCallback 钩子内完成,以避免在每次渲染时重新创建 function,特别是如果 ZC1C425268C 有点复杂,比如这个
const handleClick = useCallback(()=>
{
"...do a lot of calculations here that takes time"
},[]);
<button onClick={handleClick}>
Click me!
</button>
但是我有一个特殊情况,我希望在单击按钮以设置 state 时触发 useCallback function,这就是我想要的:
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 function 分开,如下所示,但我认为这不是一个好的方法,因为我会浪费 ZCD69B4957F06CD82918D7:
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 的依赖项上
你不知道 - 依赖项应该是(并且只是)在 function 中引用的状态/道具。
例如,如果 function 是
() => {
setCountState(countState + 1);
setToggledState(!toggledState);
}
那么依赖数组应该是
[setCountState, countState, setToggledState, toggledState]
ESLint 规则穷举-deps 可帮助您自动执行此操作。
对于您的情况,将上述内容作为唯一的依赖项是完全可以的 - 您不希望在依赖项数组中出现“哑”占位符值或任何其他依赖项。
说了这么多:
在一个反应组件中声明一个 function 来处理点击应该在 useCallback 钩子内完成,以避免在每次渲染时重新创建 function,特别是如果 ZC1C425268E68385D14AB5074C17A9 有点复杂
事实并非如此。 根据我的经验,除非 function 被传递给其他组件,否则在 99% 的情况下useCallback
是不需要或有用的 - 这似乎不是这种情况。 (无论如何,每次渲染都会重新创建 function。)
当有其他组件使用useCallback
(尤其是您不了解的组件)并且您希望向它们传递尽可能稳定的引用时,useCallback 会大放异彩,以避免不必要的重新渲染和挂钩调用。
useCallback
不会阻止 function 的创建。 它只会阻止您在每次重新渲染时获得新的 function 引用。 因此,使用useCallback
,每次渲染都会重新创建 function ,如果列出的依赖项都没有更新,则购买useCallback
会为您提供以前 function 的旧参考。
const Comp = () => {
const [state, setState] = useState([]);
const clickHandler = useCallback((ev) => {
setState(prevState => prevState.concat([/* something */])
}, [setState]);
return <button onClick={clickHandler}>Button</button>
}
我觉得你有点倒退了。 useCallback
钩子只有在返回的 memoized function 通过 props 传递给后代组件时才真正有用。 好处不是 function 很重,而是回调引用是稳定的,不会触发不必要的重新渲染。
至于使用 function 作为按钮的onClick
处理程序,它是useCallback
钩子的返回值,它被传递给按钮的onClick
处理程序,而不是单击事件处理程序的其他方式。
例子:
const clickHandler = useCallback(() => {
// do some expensive computations
}, [...dependencies]);
...
<button type="button" onClick={clickHander}>Click Me</button>
如果您没有将clickHandler
作为道具传递给另一个 React 组件,那么记忆它并没有太大的好处。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.