为何useEffect依赖数组需要包含外部函数及所有使用到的依赖?
useEffect依赖数组必须包含所有用到的依赖项的原因
首先要明确,你示例中给useEffect传空依赖数组、但回调内调用apiCall的写法,不符合React Hooks的设计规则,会存在潜在隐患,要求加入所有用到的依赖的核心原因如下:
- React会根据依赖数组的变化判断是否需要重新执行副作用回调:如果依赖数组为空,React会默认这个回调没有用到任何组件作用域内的变量/函数,只会在组件挂载时执行一次。如果你的回调实际用到了外部变量/函数却没有加入依赖,后续这个依赖的内容/引用发生变化时,
useEffect永远执行的是第一次挂载时缓存的旧版本回调,调用的也是旧的依赖,会产生预期外的bug。 - 你当前示例里的
apiCall是从外部模块导入的,看起来引用固定,似乎不会有问题,但如果后续项目迭代中apiCall的逻辑发生调整,比如增加了对环境变量、组件内部props/state的依赖,空依赖数组的写法会直接导致逻辑出错,且这类问题非常隐蔽,很难排查。
如果你确实希望这个副作用仅在组件挂载时执行一次,可以选择两种合规的实现方式:
- 确认用到的所有依赖永远不会发生变化的前提下,给空依赖数组的行加eslint忽略注释,明确标识你是刻意省略依赖:
import { apiCall } from 'api'; const App = () => { useEffect(() => { apiCall(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return <p>hi</p> }
- 用
useCallback包裹用到的函数保证引用稳定,再将其加入依赖数组,既符合Hooks规则也能实现仅执行一次的效果:
import { apiCall } from 'api'; import { useEffect, useCallback } from 'react'; const App = () => { const getApiData = useCallback(() => { apiCall(); }, []); // 这里的依赖数组同样需要包含所有useCallback回调内用到的依赖 useEffect(() => { getApiData(); }, [getApiData]) return <p>hi</p> }
内容的提问来源于stack exchange,提问作者J Seabolt
相关产品推荐
相关产品推荐

