← All tasksReact · Middle
useAsync hook
Write a useAsync(asyncFn) hook, where asyncFn returns a promise. The hook returns { status, data, error, run }.
status starts as "idle". Calling run(...args) calls asyncFn(...args) and immediately sets "pending"; on success - "success" with the result in data, on failure - "error" with the reason in error, and data reset to undefined.
Ctrl+Enter runs the tests. Tab indents; to leave the editor with the keyboard, press Esc and then Tab. Your code is saved in this browser.
Tests (3)
const { result } = renderHook(() => useAsync(() => Promise.resolve(1))); expect(result.current.status).toBe('idle'); expect(result.current.data).toBe(undefined);
const double = (x) => Promise.resolve(x * 2); const { result } = renderHook(() => useAsync(double)); act(() => { result.current.run(21); }); expect(result.current.status).toBe('pending'); await waitFor(() => expect(result.current.status).toBe('success')); expect(result.current.data).toBe(42);
const fail = () => Promise.reject(new Error('nope')); const { result } = renderHook(() => useAsync(fail)); act(() => { result.current.run(); }); await waitFor(() => expect(result.current.status).toBe('error')); expect(result.current.error.message).toBe('nope'); expect(result.current.data).toBe(undefined);