Skip to content

Commit

Permalink
feat: keep previous state in useAsyncFn
Browse files Browse the repository at this point in the history
BREAKING CHANGE: useAsyncFn now keeps hold of old result/error when called multiple times
  • Loading branch information
streamich committed Feb 4, 2020
2 parents 5bfdf65 + 062e606 commit 54ac91b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/useAsyncFn.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ const Demo = ({url}) => {
## Reference

```ts
useAsyncFn(fn, deps?: any[]);
useAsyncFn<Result, Args>(fn, deps?: any[], initialState?: AsyncState<Result>);
```
7 changes: 6 additions & 1 deletion src/useAsyncFn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ export type AsyncState<T> =
error?: undefined;
value?: undefined;
}
| {
loading: true;
error?: Error | undefined;
value?: T;
}
| {
loading: false;
error: Error;
Expand All @@ -34,7 +39,7 @@ export default function useAsyncFn<T extends FnReturningPromise>(

const callback = useCallback((...args: Parameters<T>): ReturnType<T> => {
const callId = ++lastCallId.current;
set({ loading: true });
set(prevState => ({ ...prevState, loading: true }));

return fn(...args).then(
value => {
Expand Down
27 changes: 27 additions & 0 deletions tests/useAsyncFn.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,31 @@ describe('useAsyncFn', () => {
await hook.waitForNextUpdate();
expect(hook.result.current[0]).toEqual({ loading: false, value: 2 });
});

it('should keeping value of initialState when loading', async () => {
const fetch = async () => 'new state';
const initialState = { loading: false, value: 'init state' };

const hook = renderHook<{ fn: () => Promise<string> }, [AsyncState<string>, () => Promise<string>]>(
({ fn }) => useAsyncFn(fn, [fn], initialState),
{
initialProps: { fn: fetch },
}
);

const [state, callback] = hook.result.current;
expect(state.loading).toBe(false);
expect(state.value).toBe('init state');

act(() => {
callback();
});

expect(hook.result.current[0].loading).toBe(true);
expect(hook.result.current[0].value).toBe('init state');

await hook.waitForNextUpdate();
expect(hook.result.current[0].loading).toBe(false);
expect(hook.result.current[0].value).toBe('new state');
});
});

0 comments on commit 54ac91b

Please sign in to comment.