React组件多层传递callback function调用时报"不是函数"错误
问题原因分析
- 闭包捕获旧值:如果最底层的
onRouteToChapter用了useCallback/useMemo包裹,且依赖数组没有包含routeToChapter,那么函数会捕获第一次渲染时的routeToChapter值,如果第一次渲染时该prop为undefined,即使后续prop更新为正确的函数,onRouteToChapter内部引用的还是初始的undefined值,这是你描述的现象最常见的诱因。 - 中间层prop传递截断:某层组件在传递prop时,存在条件分支,仅在部分场景下传递
routeToChapter,或者中间层组件对props做了合并/覆盖操作,把routeToChapter置为undefined。 - Props类型定义不匹配:如果用了TypeScript,
ChapterTreeItem的Props接口中routeToChapter被定义为可选参数,或者类型写错,导致运行时实际传入的值不符合预期。 - 组件重渲染时的prop丢失:中间层组件如果用了
React.memo且自定义了areEqual比较函数,忽略了routeToChapter的变化,导致子组件没有拿到更新后的prop。
排查步骤
- 检查
onRouteToChapter是否被useCallback包裹:如果是的话,确认依赖数组里是否包含了routeToChapter。 - 逐层验证prop传递链路:从Sidebar开始,依次检查每一层子组件接收和传递
routeToChapter的代码,确认没有拼写错误、没有条件漏传、没有被其他值覆盖。 - 检查是否有浅层比较忽略prop的情况:如果中间层用了
React.memo/useMemo/useCallback,确认相关依赖是否正确包含了routeToChapter,不要漏加依赖。 - 验证初始渲染值:在
ChapterTreeItem的函数最顶部和onRouteToChapter内部同时打印routeToChapter和时间戳,如果内部打印的时间戳更早,说明是闭包捕获了初始值。
解决方法
- 如果是闭包依赖缺失:给
useCallback补全routeToChapter依赖,示例:
const onRouteToChapter = useCallback(() => { routeToChapter(courseId, chapter.id as string) }, [routeToChapter, courseId, chapter.id])
- 如果是中间层prop漏传:补全所有分支下的prop传递,如果回调需要透传超过2层,建议用React Context来跨多层传递回调,避免逐层透传的问题。
- 如果是
React.memo比较逻辑问题:要么删除自定义的areEqual函数,要么把routeToChapter加入比较项。
内容的提问来源于stack exchange,提问作者BURGERFLIPPER101
相关产品推荐
相关产品推荐

