hooks icon indicating copy to clipboard operation
hooks copied to clipboard

[RFC] useEventBus

Open xbw19975 opened this issue 10 months ago • 7 comments

用于事件发布订阅.适应于跨组件调用方法,订阅全局方法,js文件中调用函数组件内方法等等..

API

useEventBus<T>(fnName: string, fn T, dep: any[]): T

Demo

const [count, setCount] = useState(0);
  const updateCount = async () => {
    setCount(count + 1)
  }
  // 订阅后任意地方都可以调用,适合跨组件,跨组件内外. 注意:组件卸载后会销毁
  useEventBus('updateCount', updateCount, [count])

  return (
    <div>
      <p>Count: {count}</p>
      <p>
        <button type="button" onClick={() => {
          // 异步提交 
          Bus.$emit('updateCount')
          // 同步提交
          Bus.$asyncEmit('updateCount')
        }}>
          Calling Bus method
        </button>
      </p>
    </div>
  );

xbw19975 avatar Apr 25 '24 06:04 xbw19975

可以试试useEventEmitter

https://ahooks.gitee.io/hooks/use-event-emitter

goodjun avatar Apr 25 '24 07:04 goodjun

可以试试useEventEmitter

https://ahooks.gitee.io/hooks/use-event-emitter

是我没看到了,确实有类似的hook.但是这个好像不支持state依赖项.也不支持异步方法的await.我可以尝试去修改一下原代码.可以给我一个提交分支的权限吗

xbw19975 avatar Apr 25 '24 08:04 xbw19975

可以试试useEventEmitter https://ahooks.gitee.io/hooks/use-event-emitter

是我没看到了,确实有类似的hook.但是这个好像不支持state依赖项.也不支持异步方法的await.我可以尝试去修改一下原代码.可以给我一个提交分支的权限吗

可以列一下使用场景吗?

goodjun avatar Apr 25 '24 08:04 goodjun

可以给我一个提交分支的权限吗

@xbw19975 fork 仓库即可贡献代码哈~ 准备长期参与 ahooks 维护的才会给主仓库的分支权限

liuyib avatar Apr 25 '24 08:04 liuyib

可以试试useEventEmitter https://ahooks.gitee.io/hooks/use-event-emitter

是我没看到了,确实有类似的hook.但是这个好像不支持state依赖项.也不支持异步方法的await.我可以尝试去修改一下原代码.可以给我一个提交分支的权限吗

可以列一下使用场景吗?

1.A组件内订阅方法,方法内有使用到state的值,把用到的state添加到依赖项中,这样其他地方调用的时候方法内才能获取到最新的状态值 2.我订阅的是一个异步方法.我在使用的地方需要保证执行的顺序,需要等待订阅的方法执行完在执行后续代码.asyncEmit 就闲的很有必要 3.当前的代码我看了,使用的是Set集合,所有订阅的方法会放到集合中.然后emit的时候会调用所有方法.这样没办法做到一对一的订阅和调用.如果有2个订阅方法.我一次只希望执行一个特点的方法,当前好像没办法实现. image 我认为这种方式的调用和真正的发布订阅有一些差距,我理想的应该是我订阅了很多方法有ABCD.然后我调用的时候emit(A),就只执行A方法.

xbw19975 avatar Apr 25 '24 08:04 xbw19975

可以给我一个提交分支的权限吗

@xbw19975 fork 仓库即可贡献代码哈~ 准备长期参与 ahooks 维护的才会给主仓库的分支权限

现在有一个问题困扰着我,因为我的代码已经完成.且test完成,如果修改原来的hook会比较麻烦.我应该去修改还是添加新的hook呢,给个建议

xbw19975 avatar Apr 25 '24 08:04 xbw19975

现在有一个问题困扰着我,因为我的代码已经完成.且test完成,如果修改原来的hook会比较麻烦.我应该去修改还是添加新的hook呢,给个建议

如果你是验证自己的想法,都可以。如果要给这个仓库贡献代码,需要修改 hook 才能被允许合入。

liuyib avatar Apr 25 '24 08:04 liuyib

useEventEmitter 在兄弟节点通信比较好用,但如果层级比较深,暂时没想到最佳实践的写法……

zdxxxxxx avatar Jun 20 '24 11:06 zdxxxxxx

我使用mitt简单实现了一版,和提问的兄弟实现的差不多

import { useEffect } from 'react'
import mitt from 'mitt'

type Events = {
  [key: string]: any
}

interface EventCallBack<T> {
  (args: T): void
}

const eventBus = mitt<Events>()

const useEventBus = <T>(
  eventName?: string,
  eventCallBack?: EventCallBack<T>,
  deps?: any[]
) => {

  useEffect(() => {
    if (eventName && eventCallBack) {
      eventBus.on(eventName, eventCallBack)
    }
    return () => {
      if (eventName && eventCallBack) {
        eventBus.off(eventName, eventCallBack)
      }
    }
  }, deps || [])

  return eventBus.emit
}

export default useEventBus

zdxxxxxx avatar Jun 20 '24 11:06 zdxxxxxx

我使用mitt简单实现了一版,和提问的兄弟实现的差不多

import { useEffect } from 'react'
import mitt from 'mitt'

type Events = {
  [key: string]: any
}

interface EventCallBack<T> {
  (args: T): void
}

const eventBus = mitt<Events>()

const useEventBus = <T>(
  eventName?: string,
  eventCallBack?: EventCallBack<T>,
  deps?: any[]
) => {

  useEffect(() => {
    if (eventName && eventCallBack) {
      eventBus.on(eventName, eventCallBack)
    }
    return () => {
      if (eventName && eventCallBack) {
        eventBus.off(eventName, eventCallBack)
      }
    }
  }, deps || [])

  return eventBus.emit
}

export default useEventBus

差不多意思. good

xbw19975 avatar Jun 25 '24 13:06 xbw19975

useEventEmitter 在兄弟节点通信比较好用,但如果层级比较深,暂时没想到最佳实践的写法……

可以结合 hox.js, 实现“跨服聊天”

q1557050025 avatar Jun 26 '24 07:06 q1557050025