Skip to content

Commit

Permalink
Merge branch 'master' into feat-useInfiniteScroll-top
Browse files Browse the repository at this point in the history
  • Loading branch information
hchlq authored Jun 12, 2024
2 parents 31436e7 + d02d146 commit 712db27
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 28 deletions.
2 changes: 1 addition & 1 deletion docs/guide/upgrade.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ useRequest has been rewritten:
- Removed `pagination` related options, it is recommended to use `usePagination` or `useAntdTable` to achieve paging ability.
- Removed `loadMore` related options, it is recommended to use `useInfiniteScroll` to achieve unlimited loading ability.
- Removed `fetchKey`, that is, deleted concurrent request.
- Removed `formatResult`, `initialData`, and `thrownError`.
- Removed `formatResult`, `initialData`, and `throwOnError`.
- The request library is no longer integrated by default, and `service` no longer supports string or object.
- Added `runAsync` and `refreshAsync`, the original `run` no longer returns Promise.
- Added error retry ability.
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/upgrade.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ useRequest 完全进行了重写:
- 删除了 `pagination` 相关属性,建议使用 `usePagination``useAntdTable` 来实现分页能力。
- 删除了 `loadMore` 相关属性,建议使用 `useInfiniteScroll` 来实现无限加载能力。
- 删除了 `fetchKey`,也就是删除了并行能力。
- 删除了 `formatResult``initialData``thrownError`
- 删除了 `formatResult``initialData``throwOnError`
- 不再默认集成请求库,`service` 不再支持字符或对象。
- 新增了 `runAsync``refreshAsync`,原来的 `run` 不再返回 Promise。
- 新增了错误重试能力。
Expand Down
45 changes: 43 additions & 2 deletions packages/hooks/src/useResetState/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { act, renderHook } from '@testing-library/react';
import useResetState from '../index';

describe('useResetState', () => {
const setUp = <S>(initialState: S) =>
const setUp = (initialState) =>
renderHook(() => {
const [state, setState, resetState] = useResetState<S>(initialState);
const [state, setState, resetState] = useResetState(initialState);

return {
state,
Expand All @@ -20,6 +20,13 @@ describe('useResetState', () => {
expect(hook.result.current.state).toEqual({ hello: 'world' });
});

it('should support functional initialValue', () => {
const hook = setUp(() => ({
hello: 'world',
}));
expect(hook.result.current.state).toEqual({ hello: 'world' });
});

it('should reset state', () => {
const hook = setUp({
hello: '',
Expand Down Expand Up @@ -49,4 +56,38 @@ describe('useResetState', () => {
});
expect(hook.result.current.state).toEqual({ count: 1 });
});

it('should keep random initial state', () => {
const random = Math.random();
const hook = setUp({
count: random,
});

act(() => {
hook.result.current.setState({ count: Math.random() });
});

act(() => {
hook.result.current.resetState();
});

expect(hook.result.current.state).toEqual({ count: random });
});

it('should support random functional initialValue', () => {
const random = Math.random();
const hook = setUp(() => ({
count: random,
}));

act(() => {
hook.result.current.setState({ count: Math.random() });
});

act(() => {
hook.result.current.resetState();
});

expect(hook.result.current.state).toEqual({ count: random });
});
});
46 changes: 25 additions & 21 deletions packages/hooks/src/useResetState/demo/demo1.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
import React from 'react';
import React, { useMemo } from 'react';
import { Button, Space } from 'antd';
import { useResetState } from 'ahooks';

interface State {
hello: string;
count: number;
}

export default () => {
const [state, setState, resetState] = useResetState<State>({
const initialValue = {
hello: '',
count: 0,
});
value: Math.random(),
};
const initialValueMemo = useMemo(() => {
return initialValue;
}, []);

const [state, setState, resetState] = useResetState(initialValue);

return (
<div>
<div>initial state: </div>
<pre>{JSON.stringify(initialValueMemo, null, 2)}</pre>
<div>current state: </div>
<pre>{JSON.stringify(state, null, 2)}</pre>
<p>
<button
type="button"
style={{ marginRight: '8px' }}
onClick={() => setState({ hello: 'world', count: 1 })}
<Space>
<Button
onClick={() =>
setState(() => ({
hello: 'world',
value: Math.random(),
}))
}
>
set hello and count
</button>

<button type="button" onClick={resetState}>
resetState
</button>
</p>
set hello and value
</Button>
<Button onClick={resetState}>resetState</Button>
</Space>
</div>
);
};
15 changes: 12 additions & 3 deletions packages/hooks/src/useResetState/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import { useState } from 'react';
import { useRef, useState } from 'react';
import type { Dispatch, SetStateAction } from 'react';
import { isFunction } from '../utils';
import useMemoizedFn from '../useMemoizedFn';
import useCreation from '../useCreation';

type ResetState = () => void;

const useResetState = <S>(
initialState: S | (() => S),
): [S, Dispatch<SetStateAction<S>>, ResetState] => {
const [state, setState] = useState(initialState);
const initialStateRef = useRef(initialState);
const initialStateMemo = useCreation(
() =>
isFunction(initialStateRef.current) ? initialStateRef.current() : initialStateRef.current,
[],
);

const [state, setState] = useState(initialStateMemo);

const resetState = useMemoizedFn(() => {
setState(initialState);
setState(initialStateMemo);
});

return [state, setState, resetState];
Expand Down

0 comments on commit 712db27

Please sign in to comment.