React useEffect:置于组件内还是自定义Hook(Service)中?
两种写法的执行效果完全一致
不管是在组件内部直接使用空依赖的useEffect,还是把这段逻辑封装到自定义Hook里,都只会在组件挂载时执行一次init(),组件卸载时执行一次shutdown(),组件多次重渲染不会触发这两个方法的重复执行。
原因很简单,React中useEffect的执行时机只由它的依赖数组决定:
- 当依赖数组为空
[]时,这个useEffect只会在组件挂载完成后触发一次,组件卸载前触发返回的清理函数(也就是shutdown())。 - 自定义Hook本质是复用组件逻辑的一种方式,Hook内部的
useEffect会绑定到调用它的组件的生命周期上,完全遵循相同的规则。
举个具体的代码对比:
组件内写法
import { useEffect } from 'react'; import { heartbeatService } from './services'; function MyComponent() { useEffect(() => { heartbeatService.init(); return () => heartbeatService.shutdown(); }, []); return <div>My Component</div>; }
自定义Hook写法
import { useEffect } from 'react'; function useHeartbeat(service) { useEffect(() => { service.init(); return () => service.shutdown(); }, []); // 空依赖数组保持不变 } // 在组件中调用 function MyComponent() { useHeartbeat(heartbeatService); return <div>My Component</div>; }
这两段代码的执行逻辑完全相同:组件挂载时启动心跳,卸载时停止心跳,中间不管组件因为props、state变化重渲染多少次,都不会再次调用init()或shutdown()。
你之前的担心是多余的——只要自定义Hook里的useEffect依赖数组是空的,就不会在组件生命周期内多次执行相关逻辑。
内容的提问来源于stack exchange,提问作者Zoltan Hernyak
相关产品推荐
相关产品推荐

