useEffect第二个参数指定规则及dispatch入参合理性疑问
useEffect相关问题解答
1. useEffect的第二个参数应当指定什么内容?
- useEffect的第二个参数是依赖项数组,需要放入所有在effect回调里用到的、会随组件渲染变化的外部值——包括组件的props、state,以及组件内部定义的、每次渲染可能重新创建的变量或函数。
- React会对比数组中每一项在前后渲染时的引用或值,只有当至少一项发生变化时,才会重新执行effect回调。
- 补充:如果不传这个数组,effect会在每次组件渲染后都执行;如果传空数组
[],effect只会在组件挂载和卸载时各执行一次。
2. 为useEffect指定一个永不变化的函数作为第二个参数是否有意义?
- 完全没有意义。
- 依赖项数组的核心作用是触发effect的重执行,要是这个函数永远不会变化,那它不会触发任何重执行,和从数组里删掉的效果完全一样。
- 另外,如果这个函数是在组件内部定义的(没经过
useCallback包裹),它其实每次渲染都会重新创建,引用会变化,这时候反而会导致effect不必要地重复执行,容易引发逻辑bug。
3. 在如下代码示例中,为何要将dispatch放入第二个参数数组中?
useEffect( () => { dispatch(asyncTestFunction({ data })) }, [data, dispatch], );
- 这里的
dispatch一般是ReduxuseDispatch钩子返回的函数,从Redux的实现来说,这个dispatch的引用是始终稳定的,理论上完全不需要放进依赖数组。 - 开发者把它加进去,大多是为了满足ESLint的
react-hooks/exhaustive-deps规则(避免lint报错),或者是防止某些自定义store实现中dispatch意外出现不稳定的情况。不过即使加进去,也不会有负面影响,只是没必要。
4. React官方文档指出无需将useState这类函数纳入该参数数组,对此存在疑问。
React官方文档关于useState的说明(翻译自日文官方文档):
useState返回的更新函数(比如调用useState得到的setXxx),在组件的整个生命周期内都是稳定不变的,不会随组件渲染而重新创建。因此,即使在effect或其他钩子中使用这些更新函数,也不需要将它们加入依赖项数组。
针对疑问的解释:
- 核心原因是
useState返回的更新函数引用永远不会变。React在组件每次渲染时,都会返回同一个更新函数的引用,所以即使依赖数组里不写它,也不会出现“依赖项变化但未被检测”的问题。 - 当然如果强行把这些更新函数放进依赖数组,也不会有问题,只是完全没必要——因为它们永远不会触发effect的重执行。
内容的提问来源于stack exchange,提问作者y.dai
相关产品推荐
相关产品推荐

