Skip to content

Commit

Permalink
feat(useRequest): add parameters trigger to the options[onBefore]
Browse files Browse the repository at this point in the history
  • Loading branch information
BastKakrolot committed Nov 15, 2023
1 parent b06cfea commit 810fcf2
Show file tree
Hide file tree
Showing 15 changed files with 196 additions and 25 deletions.
45 changes: 45 additions & 0 deletions packages/hooks/src/useRequest/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { act, renderHook, waitFor } from '@testing-library/react';
import useRequest from '../index';
import { request } from '../../utils/testingHelpers';
import { Trigger } from '../src/types';

const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});

Expand Down Expand Up @@ -202,4 +203,48 @@ describe('useRequest', () => {
expect(hook.result.current.loading).toBe(false);
hook.unmount();
});

it('useRequest trigger should return in onBefore, trigger should be correct', async () => {
let triggerValue;
const beforeCallback = (_, trigger) => {
triggerValue = trigger;
};
act(() => {
hook = setUp(request, {
onBefore: beforeCallback,
});
});
expect(triggerValue).toBe(Trigger.AUTO);
act(() => {
jest.runAllTimers();
});
act(() => {
hook.result.current.run();
});
expect(triggerValue).toBe(Trigger.RUN);
act(() => {
jest.runAllTimers();
});
act(() => {
hook.result.current.runAsync();
});
expect(triggerValue).toBe(Trigger.RUN_ASYNC);
act(() => {
jest.runAllTimers();
});
act(() => {
hook.result.current.refresh();
});
expect(triggerValue).toBe(Trigger.REFRESH);
act(() => {
jest.runAllTimers();
});
act(() => {
hook.result.current.refreshAsync();
});
expect(triggerValue).toBe(Trigger.REFRESH_ASYNC);
act(() => {
jest.runAllTimers();
});
});
});
16 changes: 14 additions & 2 deletions packages/hooks/src/useRequest/__tests__/useAutoRunPlugin.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { act, renderHook, waitFor } from '@testing-library/react';
import useRequest from '../index';
import { request } from '../../utils/testingHelpers';
import { Trigger } from '../src/types';

describe('useAutoRunPlugin', () => {
jest.useFakeTimers();
Expand All @@ -9,13 +10,19 @@ describe('useAutoRunPlugin', () => {

let hook;

it('useAutoRunPlugin ready should work', async () => {
let dep = 1;
it('useAutoRunPlugin ready should work, trigger should be correct', async () => {
let dep = 1,
triggerValue;
const beforeCallback = (_, trigger) => {
triggerValue = trigger;
};
act(() => {
hook = setUp(request, {
refreshDeps: [dep],
onBefore: beforeCallback,
});
});
expect(triggerValue).toBe(Trigger.AUTO);
expect(hook.result.current.loading).toBe(true);

act(() => {
Expand All @@ -26,7 +33,9 @@ describe('useAutoRunPlugin', () => {
dep = 2;
hook.rerender({
refreshDeps: [dep],
onBefore: beforeCallback,
});
expect(triggerValue).toBe(Trigger.REFRESH_DEPS);
expect(hook.result.current.loading).toBe(true);

act(() => {
Expand All @@ -36,7 +45,10 @@ describe('useAutoRunPlugin', () => {

hook.rerender({
refreshDeps: [dep],
onBefore: beforeCallback,
});
// 不会改变
expect(triggerValue).toBe(Trigger.REFRESH_DEPS);
expect(hook.result.current.loading).toBe(false);
});

Expand Down
24 changes: 21 additions & 3 deletions packages/hooks/src/useRequest/__tests__/usePollingPlugin.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { act, renderHook, waitFor } from '@testing-library/react';
import useRequest from '../index';
import { request } from '../../utils/testingHelpers';
import { Trigger } from '../src/types';

describe('usePollingPlugin', () => {
jest.useFakeTimers();
Expand Down Expand Up @@ -65,20 +66,24 @@ describe('usePollingPlugin', () => {
});

let hook2;
it('usePollingPlugin pollingErrorRetryCount=3 should work', async () => {
it('usePollingPlugin pollingErrorRetryCount=3 should work, trigger should be correct', async () => {
// if request error and set pollingErrorRetryCount
// and the number of consecutive failures exceeds pollingErrorRetryCount, polling stops
let errorCallback;
let errorCallback, triggerValue;
const beforeCallback = (_, trigger) => {
triggerValue = trigger;
};
act(() => {
errorCallback = jest.fn();
hook2 = setUp(() => request(0), {
pollingErrorRetryCount: 3,
pollingInterval: 100,
pollingWhenHidden: true,
onBefore: beforeCallback,
onError: errorCallback,
});
});

expect(triggerValue).toBe(Trigger.AUTO);
expect(hook2.result.current.loading).toBe(true);
expect(errorCallback).toHaveBeenCalledTimes(0);

Expand All @@ -91,26 +96,39 @@ describe('usePollingPlugin', () => {
act(() => {
jest.runAllTimers();
});

expect(triggerValue).toBe(Trigger.POLLING);

await waitFor(() => expect(errorCallback).toHaveBeenCalledTimes(2));

act(() => {
jest.runAllTimers();
});

expect(triggerValue).toBe(Trigger.POLLING);

await waitFor(() => expect(errorCallback).toHaveBeenCalledTimes(3));

act(() => {
jest.runAllTimers();
});

expect(triggerValue).toBe(Trigger.POLLING);

await waitFor(() => expect(errorCallback).toHaveBeenCalledTimes(4));

act(() => {
jest.runAllTimers();
});

expect(triggerValue).toBe(Trigger.POLLING);

expect(errorCallback).toHaveBeenCalledTimes(4);

act(() => {
hook2.result.current.run();
});
expect(triggerValue).toBe(Trigger.RUN);
act(() => {
jest.runAllTimers();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ import { act, renderHook, waitFor } from '@testing-library/react';
import { fireEvent } from '@testing-library/react';
import useRequest from '../index';
import { request } from '../../utils/testingHelpers';
import { Trigger } from '../src/types';

describe('useRefreshOnWindowFocusPlugin', () => {
jest.useFakeTimers();

const setUp = (service, options) => renderHook((o) => useRequest(service, o || options));

let hook;
it('useRefreshOnWindowFocusPlugin should work', async () => {
it('useRefreshOnWindowFocusPlugin should work, trigger should be correct', async () => {
let triggerValue;
const beforeCallback = (_, trigger) => {
triggerValue = trigger;
};
act(() => {
hook = setUp(request, {
refreshOnWindowFocus: true,
onBefore: beforeCallback,
focusTimespan: 5000,
});
});
Expand All @@ -25,7 +31,7 @@ describe('useRefreshOnWindowFocusPlugin', () => {
fireEvent.focus(window);
});
expect(hook.result.current.loading).toBe(true);

expect(triggerValue).toBe(Trigger.REFRESH_ON_WINDOW_FOCUS);
act(() => {
jest.advanceTimersByTime(2000);
});
Expand Down
22 changes: 16 additions & 6 deletions packages/hooks/src/useRequest/__tests__/useRetryPlugin.test.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,61 @@
import { act, renderHook, waitFor } from '@testing-library/react';
import useRequest from '../index';
import { request } from '../../utils/testingHelpers';
import { Trigger } from '../src/types';

describe('useRetryPlugin', () => {
jest.useFakeTimers();

const setUp = (service, options) => renderHook((o) => useRequest(service, o || options));

let hook;
it('useRetryPlugin should work', async () => {
let errorCallback;
it('useRetryPlugin should work, trigger should be correct', async () => {
let errorCallback, triggerValue;
const beforeCallback = (_, trigger) => {
triggerValue = trigger;
};
act(() => {
errorCallback = jest.fn();
hook = setUp(() => request(0), {
retryCount: 3,
onBefore: beforeCallback,
onError: errorCallback,
});
});
expect(triggerValue).toBe(Trigger.AUTO);
act(() => {
jest.setTimeout(10000);
jest.advanceTimersByTime(500);
});
expect(errorCallback).toHaveBeenCalledTimes(0);

act(() => {
jest.runAllTimers();
});
await waitFor(() => expect(errorCallback).toHaveBeenCalledTimes(1));

await waitFor(() => expect(errorCallback).toHaveBeenCalledTimes(1));
act(() => {
jest.runAllTimers();
});
await waitFor(() => expect(errorCallback).toHaveBeenCalledTimes(2));
expect(triggerValue).toBe(Trigger.RETRY);

await waitFor(() => expect(errorCallback).toHaveBeenCalledTimes(2));
act(() => {
jest.runAllTimers();
});
await waitFor(() => expect(errorCallback).toHaveBeenCalledTimes(3));
expect(triggerValue).toBe(Trigger.RETRY);

await waitFor(() => expect(errorCallback).toHaveBeenCalledTimes(3));
act(() => {
jest.runAllTimers();
});
expect(triggerValue).toBe(Trigger.RETRY);

await waitFor(() => expect(errorCallback).toHaveBeenCalledTimes(4));

act(() => {
jest.runAllTimers();
});
expect(triggerValue).toBe(Trigger.RETRY);
expect(errorCallback).toHaveBeenCalledTimes(4);
hook.unmount();

Expand Down
18 changes: 16 additions & 2 deletions packages/hooks/src/useRequest/doc/basic/basic.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const {
{
manual?: boolean,
defaultParams?: TParams,
onBefore?: (params: TParams) => void,
onBefore?: (params: TParams, trigget: Trigger) => void,
onSuccess?: (data: TData, params: TParams) => void,
onError?: (e: Error, params: TParams) => void,
onFinally?: (params: TParams, data?: TData, e?: Error) => void,
Expand Down Expand Up @@ -166,9 +166,23 @@ const {
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ------- |
| manual | <ul><li> The default is `false`. That is, the service is automatically executed during initialization. </li><li>If set to `true`, you need to manually call `run` or `runAsync` to trigger execution. </li></ul> | `boolean` | `false` |
| defaultParams | The parameters passed to the service at the first default execution | `TParams` | - |
| onBefore | Triggered before service execution | `(params: TParams) => void` | - |
| onBefore | Triggered before service execution | `(params: TParams, trigget: Trigger) => void` | - |
| onSuccess | Triggered when service resolve | `(data: TData, params: TParams) => void` | - |
| onError | Triggered when service reject | `(e: Error, params: TParams) => void` | - |
| onFinally | Triggered when service execution is complete | `(params: TParams, data?: TData, e?: Error) => void` | - |

### Trigger

| EnumValue | Description |
| ----------------------- | ------------------------- |
| AUTO | From first time auto run |
| RUN | Call `run` |
| RUN_ASYNC | Call `runAsync` |
| REFRESH | Call `refresh` |
| REFRESH_ASYNC | Call `refreshAsync` |
| POLLING | From polling |
| REFRESH_DEPS | From refreshDeps |
| REFRESH_ON_WINDOW_FOCUS | From refreshOnWindowFocus |
| RETRY | From retry |

Above we have introduced the most basic functionalities of useRequest, and then we will introduce some more advanced functionalities.
18 changes: 16 additions & 2 deletions packages/hooks/src/useRequest/doc/basic/basic.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const {
{
manual?: boolean,
defaultParams?: TParams,
onBefore?: (params: TParams) => void,
onBefore?: (params: TParams, trigget: Trigger) => void,
onSuccess?: (data: TData, params: TParams) => void,
onError?: (e: Error, params: TParams) => void,
onFinally?: (params: TParams, data?: TData, e?: Error) => void,
Expand Down Expand Up @@ -166,9 +166,23 @@ const {
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------- | ------- |
| manual | <ul><li> 默认 `false`。 即在初始化时自动执行 service。</li><li>如果设置为 `true`,则需要手动调用 `run``runAsync` 触发执行。 </li></ul> | `boolean` | `false` |
| defaultParams | 首次默认执行时,传递给 service 的参数 | `TParams` | - |
| onBefore | service 执行前触发 | `(params: TParams) => void` | - |
| onBefore | service 执行前触发 | `(params: TParams, trigget: Trigger) => void` | - |
| onSuccess | service resolve 时触发 | `(data: TData, params: TParams) => void` | - |
| onError | service reject 时触发 | `(e: Error, params: TParams) => void` | - |
| onFinally | service 执行完成时触发 | `(params: TParams, data?: TData, e?: Error) => void` | - |

### Trigger

| 枚举值 | 说明 |
| ----------------------- | -------------------- |
| AUTO | 首次自动触发 |
| RUN | 调用`run` |
| RUN_ASYNC | 调用`runAsync` |
| REFRESH | 调用`refresh` |
| REFRESH_ASYNC | 调用`refreshAsync` |
| POLLING | 来自轮询 |
| REFRESH_DEPS | 来自依赖变更 |
| REFRESH_ON_WINDOW_FOCUS | 来自屏幕聚焦重新请求 |
| RETRY | 来自错误重试 |

以上我们介绍了 useRequest 最基础的功能,接下来我们介绍一些更高级的能力。
9 changes: 6 additions & 3 deletions packages/hooks/src/useRequest/doc/basic/demo/lifeCycle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ function editUsername(username: string): Promise<void> {
export default () => {
const [state, setState] = useState('');

const { loading, run } = useRequest(editUsername, {
const { loading, run, refresh, refreshAsync } = useRequest(editUsername, {
manual: true,
onBefore: (params) => {
message.info(`Start Request: ${params[0]}`);
onBefore: (params, trigger) => {
message.info(`${trigger} :Start Request: ${params[0]}`);
},
onSuccess: (result, params) => {
setState('');
Expand All @@ -45,6 +45,9 @@ export default () => {
<button disabled={loading} type="button" onClick={() => run(state)}>
{loading ? 'Loading' : 'Edit'}
</button>
<button disabled={loading} type="button" onClick={refresh}>
refresh
</button>
</div>
);
};
Loading

0 comments on commit 810fcf2

Please sign in to comment.