You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:20:58