From eb700b9e98d562d2a8148c092cf37d4fd2daa3a8 Mon Sep 17 00:00:00 2001 From: Sakuraki <32808762+askwuxue@users.noreply.github.com> Date: Wed, 21 Aug 2024 22:23:13 +0800 Subject: [PATCH] feat: support for array as event parameter in useEventListener (#2598) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * style: change the default import to import on demand * feat: support for array as event parameter in useEventListener * feat: review后修改 --------- Co-authored-by: lxr <1076629390@qq.com> --- .../useEventListener/__tests__/index.test.ts | 28 ++++++++++++++++++ .../hooks/src/useEventListener/demo/demo3.tsx | 29 +++++++++++++++++++ .../hooks/src/useEventListener/index.en-US.md | 14 +++++---- packages/hooks/src/useEventListener/index.ts | 24 +++++++++------ .../hooks/src/useEventListener/index.zh-CN.md | 14 +++++---- 5 files changed, 90 insertions(+), 19 deletions(-) create mode 100644 packages/hooks/src/useEventListener/demo/demo3.tsx diff --git a/packages/hooks/src/useEventListener/__tests__/index.test.ts b/packages/hooks/src/useEventListener/__tests__/index.test.ts index 57094df80b..a0d9972f03 100644 --- a/packages/hooks/src/useEventListener/__tests__/index.test.ts +++ b/packages/hooks/src/useEventListener/__tests__/index.test.ts @@ -32,6 +32,34 @@ describe('useEventListener', () => { expect(state).toBe(1); }); + it('test on event list listener', async () => { + let state: number = 0; + const onClick = () => { + state++; + }; + const onKeydown = () => { + state++; + }; + const { rerender, unmount } = renderHook( + () => ( + useEventListener('click', onClick, { target: () => container }), + useEventListener('keydown', onKeydown, { target: () => container }) + ), + ); + + document.body.click(); + document.body.dispatchEvent(new KeyboardEvent('keydown')); + expect(state).toBe(0); + rerender(); + container.click(); + container.dispatchEvent(new KeyboardEvent('keydown')); + expect(state).toBe(2); + unmount(); + document.body.click(); + document.body.dispatchEvent(new KeyboardEvent('keydown')); + expect(state).toBe(2); + }); + it('test "enable" parameter', () => { let state = 0; let enable = true; diff --git a/packages/hooks/src/useEventListener/demo/demo3.tsx b/packages/hooks/src/useEventListener/demo/demo3.tsx new file mode 100644 index 0000000000..efc314083b --- /dev/null +++ b/packages/hooks/src/useEventListener/demo/demo3.tsx @@ -0,0 +1,29 @@ +/** + * title: Listen to multiple events. + * desc: Mouse hover or over the button to preview. + * + * title.zh-CN: 监听多个事件 + * desc.zh-CN: 鼠标移入移出按钮查看效果。 + */ + +import React, { useRef, useState } from 'react'; +import { useEventListener } from 'ahooks'; + +export default () => { + const ref = useRef(null); + const [value, setValue] = useState(''); + + useEventListener( + ['mouseenter', 'mouseleave'], + (ev) => { + setValue(ev.type); + }, + { target: ref }, + ); + + return ( + + ); +}; diff --git a/packages/hooks/src/useEventListener/index.en-US.md b/packages/hooks/src/useEventListener/index.en-US.md index 20b3520a2f..04823a929a 100644 --- a/packages/hooks/src/useEventListener/index.en-US.md +++ b/packages/hooks/src/useEventListener/index.en-US.md @@ -17,6 +17,10 @@ Use addEventListener elegant by Hook. +### Listen for multiple events + + + ## API ```typescript @@ -29,11 +33,11 @@ useEventListener( ### Property -| Property | Description | type | default | -| --------- | ---------------------- | --------------------- | ------- | -| eventName | Event name | `string` | - | -| handler | Callback function | `(ev: Event) => void` | - | -| options | More options(optional) | `Options` | - | +| Property | Description | type | default | +| --------- | ---------------------- | ---------------------- | ------- | +| eventName | Event name | `string` \| `string[]` | - | +| handler | Callback function | `(ev: Event) => void` | - | +| options | More options(optional) | `Options` | - | ### Options diff --git a/packages/hooks/src/useEventListener/index.ts b/packages/hooks/src/useEventListener/index.ts index b066846722..0848466c95 100644 --- a/packages/hooks/src/useEventListener/index.ts +++ b/packages/hooks/src/useEventListener/index.ts @@ -36,13 +36,13 @@ function useEventListener( options?: Options, ): void; function useEventListener( - eventName: string, + eventName: string | string[], handler: (event: Event) => void, options?: Options, ): void; -function useEventListener(eventName: string, handler: noop, options: Options): void; +function useEventListener(eventName: string | string[], handler: noop, options: Options): void; -function useEventListener(eventName: string, handler: noop, options: Options = {}) { +function useEventListener(eventName: string | string[], handler: noop, options: Options = {}) { const { enable = true } = options; const handlerRef = useLatest(handler); @@ -62,15 +62,21 @@ function useEventListener(eventName: string, handler: noop, options: Options = { return handlerRef.current(event); }; - targetElement.addEventListener(eventName, eventListener, { - capture: options.capture, - once: options.once, - passive: options.passive, + const eventNameArray = Array.isArray(eventName) ? eventName : [eventName]; + + eventNameArray.forEach((event) => { + targetElement.addEventListener(event, eventListener, { + capture: options.capture, + once: options.once, + passive: options.passive, + }); }); return () => { - targetElement.removeEventListener(eventName, eventListener, { - capture: options.capture, + eventNameArray.forEach((event) => { + targetElement.removeEventListener(event, eventListener, { + capture: options.capture, + }); }); }; }, diff --git a/packages/hooks/src/useEventListener/index.zh-CN.md b/packages/hooks/src/useEventListener/index.zh-CN.md index b3606f1046..05506c56b1 100644 --- a/packages/hooks/src/useEventListener/index.zh-CN.md +++ b/packages/hooks/src/useEventListener/index.zh-CN.md @@ -17,6 +17,10 @@ nav: +### 监听多个事件 + + + ## API ```typescript @@ -29,11 +33,11 @@ useEventListener( ### Params -| 参数 | 说明 | 类型 | 默认值 | -| --------- | ---------- | --------------------- | ------ | -| eventName | 事件名称 | `string` | - | -| handler | 处理函数 | `(ev: Event) => void` | - | -| options | 设置(可选) | `Options` | - | +| 参数 | 说明 | 类型 | 默认值 | +| --------- | ---------- | ---------------------- | ------ | +| eventName | 事件名称 | `string` \| `string[]` | - | +| handler | 处理函数 | `(ev: Event) => void` | - | +| options | 设置(可选) | `Options` | - | ### Options