React.useCallback是否会对内部声明的柯里化函数进行缓存?
问题1:handleClick返回的赋值给onClick的函数每次重渲染都是新的吗?
是,每次都会生成全新的函数。
问题2:useCallback会缓存嵌套的返回函数吗?
不会,useCallback只会缓存你传入的最外层函数。
useCallback的缓存逻辑仅作用于你直接传给它的函数本身:在你的示例里,被缓存的是接收newState作为参数的这层函数,只要它的依赖项没有变化,handleClick的引用永远不变,你传给Child组件的handleClick prop也会始终稳定。
但你在JSX中写onClick={handleClick("foo")}的时候,相当于每次渲染都会当场执行一次handleClick函数,JS的函数执行机制决定了,每次调用函数返回的内部匿名函数都是一个全新的引用,这和外层的handleClick是否被useCallback缓存没有关系。
这种写法的核心价值是保证传入Child的handleClick prop稳定,如果你的Child组件用React.memo包裹,就可以避免Child因为prop变化产生不必要的重渲染,这个收益是成立的。至于绑定到onClick上的内层函数每次新建的开销非常低,绝大多数业务场景下完全可以忽略,不需要额外优化。
如果确实需要缓存内层函数(比如你需要对内部的button也做memo避免不必要重渲染),可以用useRef配合Map做自定义缓存,示例如下:
const cacheRef = useRef(new Map()); const handleClick = useCallback( (newState) => { if (!cacheRef.current.has(newState)) { cacheRef.current.set(newState, () => setState(newState)); } return cacheRef.current.get(newState); }, [setState] );
这样同一个newState对应的处理函数永远是同一个引用,不过如果没有特殊的性能优化需求,不建议额外加这层逻辑,反而会增加代码复杂度。
内容的提问来源于stack exchange,提问作者Ramesh Reddy
相关产品推荐
相关产品推荐

