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

React Hooks是否可以生成新Hooks?相关实现规则与场景实践问询

结论

该实现方案完全符合React Hooks规范,是官方推荐的逻辑复用实践。
React的Hook规则仅约束Hook的调用时机,要求必须在React函数组件、或其他自定义Hook的顶层调用,不会限制Hook的定义和生成方式,你要实现的封装属于标准的自定义Hook衍生用法。

实现参考

方案1:单独封装通用自定义Hook

// 通用自定义Hook,接收subscribe实例和回调作为参数
function useSubscriptionEffect<T>(
  subscribe: SubscriptionManager<T>['subscribe'],
  fn: (data: T) => void
) {
  useEffect(() => {
    return subscribe(fn);
  }, [subscribe, fn]);
}

为了避免effect不必要的重复执行,建议给原useSubscription返回的方法加useCallback包裹保证引用稳定:

export function useSubscription<T = any>(): SubscriptionManager<T> {
  const subscribersRef = useRef<((data: T) => void)[]>([]);
  // 用useCallback包裹,保证引用永久稳定
  const subscribe = useCallback((fn: (data: T) => void) => {
    subscribersRef.current.push(fn);
    return () => {
      subscribersRef.current = subscribersRef.current.filter(
        (subscription) => !Object.is(subscription, fn)
      );
    };
  }, []);
  const notify = useCallback((data: T) => {
    subscribersRef.current.forEach((fn) => fn(data));
  }, []);
  return { subscribe, notify };
}

使用示例:

function DemoComponent() {
  const { subscribe, notify } = useSubscription<string>();
  // 调用自定义Hook,无需重复写useEffect样板代码
  useSubscriptionEffect(subscribe, (data) => {
    console.log('收到通知:', data);
  });
  return <button onClick={() => notify('测试消息')}>发送通知</button>;
}

方案2:直接从useSubscription返回预绑定的Hook

如果你希望更易用,也可以直接把封装好的Hook作为useSubscription的返回值:

export function useSubscription<T = any>() {
  const subscribersRef = useRef<((data: T) => void)[]>([]);
  const subscribe = useCallback((fn: (data: T) => void) => {
    subscribersRef.current.push(fn);
    return () => {
      subscribersRef.current = subscribersRef.current.filter(s => !Object.is(s, fn));
    };
  }, []);
  const notify = useCallback((data: T) => {
    subscribersRef.current.forEach(fn => fn(data));
  }, []);
  // 预绑定当前subscribe实例的自定义Hook
  const useSubscriptionEffect = useCallback((fn: (data: T) => void) => {
    useEffect(() => {
      return subscribe(fn);
    }, [fn]);
  }, [subscribe]);
  return { subscribe, notify, useSubscriptionEffect };
}

使用示例:

function DemoComponent() {
  const { notify, useSubscriptionEffect } = useSubscription<string>();
  // 直接调用返回的绑定后Hook
  useSubscriptionEffect((data) => {
    console.log('收到通知:', data);
  });
  return <button onClick={() => notify('测试消息')}>发送通知</button>;
}

两种实现均完全合规,可根据业务需求选择。

内容的提问来源于stack exchange,提问作者Archimedes Trajano

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:06:03