React useMemo缺失依赖告警、函数失效及useCallback依赖修复方案问询
问题根因
你遇到的useMemo依赖告警、加了依赖后函数无法正常运行的核心原因是:
- 初始定义的
openTutorial、deleteTutorial没有做引用稳定处理,每次组件渲染都会生成新的函数实例 - 如果你直接把这两个不稳定的函数加入
useMemo依赖,会导致columns每次组件渲染都重新计算,如果你用的是React Table这类依赖columns引用判断是否重渲染的库,轻则触发不必要的表格重渲染,重则闭包捕获的上下文变量错误导致功能异常。
正确修复方案
- 首先用
useCallback包裹openTutorial和deleteTutorial,稳定函数引用:
// useCallback的依赖只需要放不稳定的外部变量,ref、TutorialDataService这类引用稳定的不需要加 const openTutorial = useCallback((rowIndex) => { const id = tutorialsRef.current[rowIndex].id; props.history.push("/tutorials/" + id); }, [props.history]); const deleteTutorial = useCallback((rowIndex) => { const id = tutorialsRef.current[rowIndex].id; TutorialDataService.remove(id).then((response) => { props.history.push("/tutorials"); let newTutorials = [...tutorialsRef.current]; newTutorials.splice(rowIndex, 1); setTutorials(newTutorials); }).catch((e) => { console.log(e); }); }, [props.history, setTutorials]);
- 再把稳定后的两个函数加入
columns的useMemo依赖数组即可,不会再触发告警,也不会导致columns频繁重计算:
const columns = useMemo(() => [ // 原有columns逻辑不变 ], [openTutorial, deleteTutorial]);
补充问题解答
你给出的useCallback修复方式可以解决告警,但存在冗余:
- 不需要额外封装
callHistory,直接把props.history加入deleteTutorial的useCallback依赖即可,效果完全一致,还少了一层封装 - 你当前的写法本身是能正常运行的,因为react-router的
props.history引用全程稳定,callHistory和deleteTutorial的引用也会保持稳定,不会触发不必要的重渲染。
内容的提问来源于stack exchange,提问作者olimih
相关产品推荐
相关产品推荐

