为何useMemo包裹的防抖函数在useCallback中调用报错?
问题原因解析
第一段代码报错的核心原因
你第一段代码里的useMemo回调没有返回防抖函数:
const handleSearch = useMemo(() => { _.debounce(text => { console.log(text); }); // 这里缺少return,导致useMemo最终返回undefined }, []);
_.debounce()确实会生成一个防抖后的函数,但你只在useMemo的回调里执行了这个方法,却没把它返回出去。最终handleSearch的值是undefined,调用undefined(text)自然就会触发“handleSearch is not a function”的错误。
如果要让这段代码生效,只需给useMemo的回调加上return:
const handleSearch = useMemo(() => { return _.debounce(text => { console.log(text); }, 1000); // 建议显式指定防抖延迟,lodash默认值可能不符合预期 }, []);
为什么useRef版本能正常工作
用useRef的写法能正常运行,主要有两个原因:
- 引用稳定:
useRef的.current属性在组件整个生命周期内引用不会改变,不会因为组件重渲染而重新创建防抖函数——如果每次渲染都生成新的防抖函数,防抖逻辑会完全失效。 - 直接存储函数实例:你直接把
_.debounce()生成的防抖函数存在了ref对象里,通过handleSearch.current就能直接调用这个函数实例,不存在“不是函数”的类型问题。
另外补充:React官方不推荐用useMemo缓存函数,它的设计初衷是缓存计算开销大的数值。如果要缓存函数,更合适的选择是useCallback,比如:
const handleSearch = useCallback(_.debounce(text => { console.log(text); }, 1000), []);
内容的提问来源于stack exchange,提问作者DinhNguyen
相关产品推荐
相关产品推荐

