You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在传入useCallback的函数内部调用setState?

结论

官方文档的限制仅针对直接作为useMemo入参的内联函数内部,与你缓存的fn本身无关,自然也不限制useCallback包裹的函数内部写副作用。


具体解释

  1. 首先明确两者的执行时机差异
    你写的代码const res = useMemo(() => fn, []);里,有两个完全独立的函数:
  • 传给useMemo的匿名函数() => fn:会在组件渲染过程中同步执行,React需要拿到它的返回值来生成缓存的res。渲染过程中不能执行副作用(比如setState)是因为会触发重复渲染,甚至死循环,这就是官方文档限制的范围。
  • 被缓存的fn:在渲染阶段完全不会被执行,只是被当做一个普通值存在res里而已。它的执行时机完全由你控制,只要你不在渲染过程中直接调用它,内部写任何逻辑都符合规范。
  1. 关于useCallback的误解澄清
    useCallback(fn, deps)等价于useMemo(() => fn, deps)的本质,是说两者都是用来缓存fn这个函数值,不会在渲染阶段执行fn本身。
    我们日常把useCallback返回的函数作为点击事件回调、useEffect依赖、异步任务回调使用时,执行时机都不在渲染过程中,所以完全可以在里面写setState、接口请求这类副作用,这也是React的常规用法。

反例参考

只有你在渲染过程中直接调用useCallback返回的函数时,才会触发问题,这种写法本身就是错误的:

const addCount = useCallback(() => {
  setCount(prev => prev + 1)
}, [])

// 错误写法:渲染期间直接调用,会触发死循环
addCount()

return <button onClick={addCount}>正常调用,没有问题</button>

内容的提问来源于stack exchange,提问作者gmoniava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 23:00:01