Testing async setState
binyellow opened this issue · 1 comments
binyellow commented
What is your question:
I wrote a hook to return a function, and after executing the returned function, change the state according to the promise state, but I can't get the latest state in the test
// hooks file
import useMergedState from "rc-util/lib/hooks/useMergedState";
import { useCallback } from "react";
import { useRequestLoadingProps, useRequestLoadingRes } from "./index.type";
function isThenable(thing?: PromiseLike<any>): boolean {
return !!(thing && !!thing.then);
}
const useRequestLoading = (props: useRequestLoadingProps): useRequestLoadingRes => {
const { fn, loading: oLoading } = props;
const [loading, setLoading] = useMergedState(false, { value: oLoading });
const next = useCallback(() => {
let returnValueOfFn = typeof fn === "function" ? fn?.() : null;
if (!isThenable(returnValueOfFn)) {
return;
}
setLoading(true);
returnValueOfFn!.finally(() => {
setLoading(false);
});
}, []);
return [next, loading, { setLoading }];
};
export default useRequestLoading;
// test file
import { act, renderHook } from "@testing-library/react-hooks";
import useRequestLoading from "../useRequestLoading";
export function request(t = 1000, req, data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("timer call ===>", t, data);
if (req === 0) {
reject(new Error(data || "fail"));
} else {
resolve(data || "success");
}
}, t);
});
}
export function sleep(t) {
return request(t);
}
export const getCurrent = (hook) => hook?.result?.current;
test("测试requestLoading", async () => {
const requestLoading = (props) => {
return renderHook(() => useRequestLoading(props));
};
const fn = () => request(1000, 1, { ret: 0, message: "success!" });
let hook;
let current;
jest.useFakeTimers();
act(() => {
hook = requestLoading({ fn });
});
await act(async () => {
current = getCurrent(hook);
current[0]();
// **This should be loading, but I don't know why I can't get the latest state**
console.log(1, current);
jest.runAllTimers();
});
console.log(2, current);
});
binyellow commented
The definition of hook needs to be advanced