From 0b50ba3af39f673cf60a884fd35f370bb04898fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=A3=E5=8D=9A=E6=96=87?= <1030698842@qq.com> Date: Thu, 25 Apr 2024 17:51:59 +0800 Subject: [PATCH 1/2] feat(useEventBus): support-new-way-publish-subscribe --- .../hooks/src/Bus/__tests__/index.test.ts | 14 ++++++ packages/hooks/src/Bus/index.ts | 47 +++++++++++++++++++ .../src/useEventBus/__tests__/index.test.ts | 20 ++++++++ packages/hooks/src/useEventBus/demo/demo1.tsx | 39 +++++++++++++++ packages/hooks/src/useEventBus/index.en-US.md | 19 ++++++++ packages/hooks/src/useEventBus/index.tsx | 15 ++++++ packages/hooks/src/useEventBus/index.zh-CN.md | 21 +++++++++ 7 files changed, 175 insertions(+) create mode 100644 packages/hooks/src/Bus/__tests__/index.test.ts create mode 100644 packages/hooks/src/Bus/index.ts create mode 100644 packages/hooks/src/useEventBus/__tests__/index.test.ts create mode 100644 packages/hooks/src/useEventBus/demo/demo1.tsx create mode 100644 packages/hooks/src/useEventBus/index.en-US.md create mode 100644 packages/hooks/src/useEventBus/index.tsx create mode 100644 packages/hooks/src/useEventBus/index.zh-CN.md diff --git a/packages/hooks/src/Bus/__tests__/index.test.ts b/packages/hooks/src/Bus/__tests__/index.test.ts new file mode 100644 index 0000000000..a47abf9dbf --- /dev/null +++ b/packages/hooks/src/Bus/__tests__/index.test.ts @@ -0,0 +1,14 @@ +import { Bus } from '../index'; + +describe('Bus', () => { + it('should work for useEffect', () => { + let mountedState = 1; + //订阅 + Bus.$on('updateMountedState', (args) => { + mountedState = args; + }); + //发布 + Bus.$emit('updateMountedState', 2); + expect(mountedState).toBe(2); + }); +}); diff --git a/packages/hooks/src/Bus/index.ts b/packages/hooks/src/Bus/index.ts new file mode 100644 index 0000000000..af38acc20f --- /dev/null +++ b/packages/hooks/src/Bus/index.ts @@ -0,0 +1,47 @@ +interface TypeEventBus { + callbacks: any; + $off: (name: string) => void; + $emit: (name: string, ...args: any[]) => any; + $asyncEmit: (name: string, ...args: any[]) => any; + $on: (name: string, fn: any) => void; +} + +export const Bus: TypeEventBus = { + callbacks: {}, + + // 解除监听 用的比较少 + $off(name) { + this.callbacks[name] = null; + }, + + // 提交通信封装 + $emit(name, ...args) { + const cbs = this.callbacks[name]; + let result = undefined; + if (cbs) { + cbs.forEach((c: any) => { + result = c.call(this, ...args); + }); + } + return result; + }, + + async $asyncEmit(name, ...args) { + const cbs = this.callbacks[name]; + let result = undefined; + if (cbs) { + for (let i = 0; i < cbs.length; i++) { + const c = cbs[i]; + result = await c.call(this, ...args); + } + } + return result; + }, + + // 监听封装 + $on(name, fn) { + (this.callbacks[name] || (this.callbacks[name] = [])).push(fn); + }, +}; + +export default Bus; diff --git a/packages/hooks/src/useEventBus/__tests__/index.test.ts b/packages/hooks/src/useEventBus/__tests__/index.test.ts new file mode 100644 index 0000000000..403ecd7bc3 --- /dev/null +++ b/packages/hooks/src/useEventBus/__tests__/index.test.ts @@ -0,0 +1,20 @@ +import { renderHook } from '@testing-library/react'; +import useEventBus from '../index'; +import Bus from '../../Bus'; + +describe('useEventBus', () => { + it('test in component', async () => { + let mountedState = 1; + const hook = renderHook(() => { + const fc = (args) => { + mountedState = args; + }; + useEventBus('订阅方法名称', fc, []); + //发布 + Bus.$emit('订阅方法名称', 2); + }); + expect(mountedState).toBe(1); + hook.rerender(); + expect(mountedState).toBe(2); + }); +}); diff --git a/packages/hooks/src/useEventBus/demo/demo1.tsx b/packages/hooks/src/useEventBus/demo/demo1.tsx new file mode 100644 index 0000000000..118202fcb9 --- /dev/null +++ b/packages/hooks/src/useEventBus/demo/demo1.tsx @@ -0,0 +1,39 @@ +/** + * title: Basic usage + * desc: `useEventBus` Be synonymous with `Bus.$on`,However, you can depend on the value of the state and remount the function when dependent on updates,Once subscribed, methods can be called from anywhere + * + * title.zh-CN: 基础用法 + * desc.zh-CN: `useEventBus` 用法等同于 `Bus.$on`,但是可以依赖状态的值,依赖更新时重新挂载函数。订阅后任何地方都可以调用方法 + */ + +import React, { useState } from 'react'; +import { Bus, useEventBus } from 'ahooks'; + +export default () => { + const [count, setCount] = useState(0); + + const updateCount = async () => { + setCount(count + 1); + }; + // 订阅后任意地方都可以调用,适合跨组件,跨组件内外. 注意:组件卸载后会销毁 + useEventBus('updateCount', updateCount, [count]); + + return ( +
Count: {count}
++ +
+
+
+## API
+
+```typescript
+// hooks 订阅
+useEventBus('Subscription method name',Subscribe to callback methods,[dependency]);
+```
diff --git a/packages/hooks/src/useEventBus/index.tsx b/packages/hooks/src/useEventBus/index.tsx
new file mode 100644
index 0000000000..694ad79bf4
--- /dev/null
+++ b/packages/hooks/src/useEventBus/index.tsx
@@ -0,0 +1,15 @@
+import { useEffect } from 'react';
+import Bus from '../Bus';
+
+export const useEventBus = (callbackName: string, callback: Function, deps?: any[]) => {
+ useEffect(() => {
+ Bus.$on(callbackName, callback);
+ return () => {
+ Bus.$off(callbackName);
+ };
+ }, deps || []);
+
+ return [];
+};
+
+export default useEventBus;
diff --git a/packages/hooks/src/useEventBus/index.zh-CN.md b/packages/hooks/src/useEventBus/index.zh-CN.md
new file mode 100644
index 0000000000..7f85ef0697
--- /dev/null
+++ b/packages/hooks/src/useEventBus/index.zh-CN.md
@@ -0,0 +1,21 @@
+---
+nav:
+ path: /hooks
+---
+
+# useEventBus
+
+`useEventBus` 用法等同于 `Bus.$on`,但是可以依赖状态的值,依赖更新时重新挂载函数。订阅后任何地方都可以调用方法
+
+## 代码演示
+
+### 基础用法
+
+
+
+## API
+
+```typescript
+// hooks 订阅
+useEventBus('订阅方法名称',订阅回调方法,[依赖项]);
+```
From 71bd837f3a41b02fdb758d32a0f8ba5ff3ff0a78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=A3=E5=8D=9A=E6=96=87?= <1030698842@qq.com>
Date: Mon, 1 Jul 2024 19:22:55 +0800
Subject: [PATCH 2/2] refactor/useEventEmitter
---
.../hooks/src/Bus/__tests__/index.test.ts | 14 -----
packages/hooks/src/Bus/index.ts | 47 ----------------
.../src/useEventBus/__tests__/index.test.ts | 20 -------
packages/hooks/src/useEventBus/demo/demo1.tsx | 39 -------------
packages/hooks/src/useEventBus/index.en-US.md | 19 -------
packages/hooks/src/useEventBus/index.tsx | 15 -----
packages/hooks/src/useEventBus/index.zh-CN.md | 21 -------
.../useEventEmitter/__tests__/index.test.ts | 15 +++++
.../hooks/src/useEventEmitter/demo/demo2.tsx | 55 +++++++++++++++++++
.../hooks/src/useEventEmitter/index.en-US.md | 36 +++++++++++-
packages/hooks/src/useEventEmitter/index.ts | 46 ++++++++++------
.../hooks/src/useEventEmitter/index.zh-CN.md | 42 ++++++++++++--
12 files changed, 173 insertions(+), 196 deletions(-)
delete mode 100644 packages/hooks/src/Bus/__tests__/index.test.ts
delete mode 100644 packages/hooks/src/Bus/index.ts
delete mode 100644 packages/hooks/src/useEventBus/__tests__/index.test.ts
delete mode 100644 packages/hooks/src/useEventBus/demo/demo1.tsx
delete mode 100644 packages/hooks/src/useEventBus/index.en-US.md
delete mode 100644 packages/hooks/src/useEventBus/index.tsx
delete mode 100644 packages/hooks/src/useEventBus/index.zh-CN.md
create mode 100644 packages/hooks/src/useEventEmitter/demo/demo2.tsx
diff --git a/packages/hooks/src/Bus/__tests__/index.test.ts b/packages/hooks/src/Bus/__tests__/index.test.ts
deleted file mode 100644
index a47abf9dbf..0000000000
--- a/packages/hooks/src/Bus/__tests__/index.test.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { Bus } from '../index';
-
-describe('Bus', () => {
- it('should work for useEffect', () => {
- let mountedState = 1;
- //订阅
- Bus.$on('updateMountedState', (args) => {
- mountedState = args;
- });
- //发布
- Bus.$emit('updateMountedState', 2);
- expect(mountedState).toBe(2);
- });
-});
diff --git a/packages/hooks/src/Bus/index.ts b/packages/hooks/src/Bus/index.ts
deleted file mode 100644
index af38acc20f..0000000000
--- a/packages/hooks/src/Bus/index.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-interface TypeEventBus {
- callbacks: any;
- $off: (name: string) => void;
- $emit: (name: string, ...args: any[]) => any;
- $asyncEmit: (name: string, ...args: any[]) => any;
- $on: (name: string, fn: any) => void;
-}
-
-export const Bus: TypeEventBus = {
- callbacks: {},
-
- // 解除监听 用的比较少
- $off(name) {
- this.callbacks[name] = null;
- },
-
- // 提交通信封装
- $emit(name, ...args) {
- const cbs = this.callbacks[name];
- let result = undefined;
- if (cbs) {
- cbs.forEach((c: any) => {
- result = c.call(this, ...args);
- });
- }
- return result;
- },
-
- async $asyncEmit(name, ...args) {
- const cbs = this.callbacks[name];
- let result = undefined;
- if (cbs) {
- for (let i = 0; i < cbs.length; i++) {
- const c = cbs[i];
- result = await c.call(this, ...args);
- }
- }
- return result;
- },
-
- // 监听封装
- $on(name, fn) {
- (this.callbacks[name] || (this.callbacks[name] = [])).push(fn);
- },
-};
-
-export default Bus;
diff --git a/packages/hooks/src/useEventBus/__tests__/index.test.ts b/packages/hooks/src/useEventBus/__tests__/index.test.ts
deleted file mode 100644
index 403ecd7bc3..0000000000
--- a/packages/hooks/src/useEventBus/__tests__/index.test.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { renderHook } from '@testing-library/react';
-import useEventBus from '../index';
-import Bus from '../../Bus';
-
-describe('useEventBus', () => {
- it('test in component', async () => {
- let mountedState = 1;
- const hook = renderHook(() => {
- const fc = (args) => {
- mountedState = args;
- };
- useEventBus('订阅方法名称', fc, []);
- //发布
- Bus.$emit('订阅方法名称', 2);
- });
- expect(mountedState).toBe(1);
- hook.rerender();
- expect(mountedState).toBe(2);
- });
-});
diff --git a/packages/hooks/src/useEventBus/demo/demo1.tsx b/packages/hooks/src/useEventBus/demo/demo1.tsx
deleted file mode 100644
index 118202fcb9..0000000000
--- a/packages/hooks/src/useEventBus/demo/demo1.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * title: Basic usage
- * desc: `useEventBus` Be synonymous with `Bus.$on`,However, you can depend on the value of the state and remount the function when dependent on updates,Once subscribed, methods can be called from anywhere
- *
- * title.zh-CN: 基础用法
- * desc.zh-CN: `useEventBus` 用法等同于 `Bus.$on`,但是可以依赖状态的值,依赖更新时重新挂载函数。订阅后任何地方都可以调用方法
- */
-
-import React, { useState } from 'react';
-import { Bus, useEventBus } from 'ahooks';
-
-export default () => {
- const [count, setCount] = useState(0);
-
- const updateCount = async () => {
- setCount(count + 1);
- };
- // 订阅后任意地方都可以调用,适合跨组件,跨组件内外. 注意:组件卸载后会销毁
- useEventBus('updateCount', updateCount, [count]);
-
- return (
- Count: {count}
-- -
-
-
-## API
-
-```typescript
-// hooks 订阅
-useEventBus('Subscription method name',Subscribe to callback methods,[dependency]);
-```
diff --git a/packages/hooks/src/useEventBus/index.tsx b/packages/hooks/src/useEventBus/index.tsx
deleted file mode 100644
index 694ad79bf4..0000000000
--- a/packages/hooks/src/useEventBus/index.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { useEffect } from 'react';
-import Bus from '../Bus';
-
-export const useEventBus = (callbackName: string, callback: Function, deps?: any[]) => {
- useEffect(() => {
- Bus.$on(callbackName, callback);
- return () => {
- Bus.$off(callbackName);
- };
- }, deps || []);
-
- return [];
-};
-
-export default useEventBus;
diff --git a/packages/hooks/src/useEventBus/index.zh-CN.md b/packages/hooks/src/useEventBus/index.zh-CN.md
deleted file mode 100644
index 7f85ef0697..0000000000
--- a/packages/hooks/src/useEventBus/index.zh-CN.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-nav:
- path: /hooks
----
-
-# useEventBus
-
-`useEventBus` 用法等同于 `Bus.$on`,但是可以依赖状态的值,依赖更新时重新挂载函数。订阅后任何地方都可以调用方法
-
-## 代码演示
-
-### 基础用法
-
-
-
-## API
-
-```typescript
-// hooks 订阅
-useEventBus('订阅方法名称',订阅回调方法,[依赖项]);
-```
diff --git a/packages/hooks/src/useEventEmitter/__tests__/index.test.ts b/packages/hooks/src/useEventEmitter/__tests__/index.test.ts
index fedefffba5..a605b76026 100644
--- a/packages/hooks/src/useEventEmitter/__tests__/index.test.ts
+++ b/packages/hooks/src/useEventEmitter/__tests__/index.test.ts
@@ -13,6 +13,9 @@ describe('useEventEmitter', () => {
event$.useSubscription((val) => {
setCount((c) => c + val + 10);
});
+ event$.useSubscription(async (val) => {
+ setCount((c) => c + val + 10);
+ }, 'async');
return {
event$,
count,
@@ -30,4 +33,16 @@ describe('useEventEmitter', () => {
});
expect(hook.result.current.count).toBe(26);
});
+
+ it('asyncEmit and subscribe should work', async () => {
+ const hook = setUp();
+ await act(async () => {
+ await hook.result.current.event$.asyncEmit(1, 'async');
+ });
+ expect(hook.result.current.count).toBe(11);
+ await act(async () => {
+ await hook.result.current.event$.asyncEmit(2, 'async');
+ });
+ expect(hook.result.current.count).toBe(23);
+ });
});
diff --git a/packages/hooks/src/useEventEmitter/demo/demo2.tsx b/packages/hooks/src/useEventEmitter/demo/demo2.tsx
new file mode 100644
index 0000000000..a6c5d9267a
--- /dev/null
+++ b/packages/hooks/src/useEventEmitter/demo/demo2.tsx
@@ -0,0 +1,55 @@
+/**
+ * title: Invoke asynchronous methods arbitrarily across components
+ * desc: A component creates a 'getData' event. By calling 'getData' in component B, component A receives the notification
+ *
+ * title.zh-CN: 任意跨组件调用异步方法
+ * desc.zh-CN: A组件创建了一个 `getData` 事件。在 B组件 中调用 `getData` ,A 组件就可以收到通知。
+ */
+
+import React, { useRef, FC, useState } from 'react';
+import { useEventEmitter } from 'ahooks';
+
+const ComponentA: FC = function (props) {
+ const inputRef = useRef{data}
+ +
+### Asynchronous events shared by different components (synchronously executed)
+
+
+
## API
### Params
@@ -49,5 +82,6 @@ const result: Result = useEventEmitter
+### 不同组件共享异步事件(可同步执行)
+
+
+
## API
```typescript
@@ -45,7 +78,8 @@ const result: Result = useEventEmitter