在Jest中API模拟后的useEffect中的无限循环



在我正在处理的组件中看到一些奇怪的东西。所以,我有一个服务器端分页表,在每个API调用上,我都将新记录推送到现有数组。我正在使用fetchBaseQuery进行API调用。

实现代码

let response = useGetQuery(request); // This hook will perform the API call
const records =
response.data?.records;
React.useEffect(() => {
if (records) {
setTableRecords((prevState: any) => [
...prevState,
...records,
]);
}
}, [records]);

这个

的测试用例

jest.mock("../endpoints", () => ({
...jest.requireActual("../endpoints"),
useGetQuery: () => ({
isSuccess: true,
data: {
message: "Success",
records: [], // It gets into infinte loop if I provide this key while mocking
},
}),
}));
test("should mount", () => {
const component = renderer.create(<SomeComponent/>);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});

作为,根据我的理解,如果我们在useEffect钩子中使用array作为依赖项,它可能会导致无限循环,因为React使用浅比较来检查依赖项的引用是否发生了变化。为了解决这个问题,我尝试使用useRef钩子,但这并不工作,因为我的用例useRef不通知你当它的内容改变。

然后我尝试通过使response.data对象作为useEffect钩子的依赖项,但根据肤浅的比较,它也导致无限循环,所以我然后试图用useMemo钩子修复它,但没有运气,就像我传递依赖项作为对象一样,它再次导致同样的问题&不传递依赖对我来说是行不通的。

有没有其他方法可以让我更好地处理这种情况?

如果数组不是太大,则将在依赖数组中传递的数组字符串化。

let response = useGetQuery(request); // This hook will perform the API call
const records =
response.data?.records;
React.useEffect(() => {
if (records) {
setTableRecords((prevState: any) => [
...prevState,
...records,
]);
}
}, [JSON.stringify(records)]);

我使用useEffect钩子,但不是将api响应作为数组传递,而是使用一些参数,例如,如果我调用api来获取基于类别的图像,我将只在类别更改时调用api:

const [state, setState] = useState({
loading: true,
data: [],
});
useEffect(() => {
myApiMethod(category).then((gifs) => {
setState({
loading: false,
data: gifs,
});
});
}, [category]);

不需要更新原始代码,我们需要确保模拟的useGetQuery在我们的测试代码中被正确地设置为返回一个稳定的值。

jest.mock("../endpoints");
const useGetQueryMock = useGetQuery as jest.MockedFunction<
typeof useGetQuery>;
test("should mount", () => {
useGetQueryMock.mockReturnValue({
{
isSuccess: true,
data: {
message: "Success",
records: [],
},
}
});
const component = renderer.create(<SomeComponent/>);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});

最新更新