renderHook doesn't work with the custom hook that has useMemo
mzbac opened this issue · 2 comments
react-hooks-testing-libraryversion: 7.0.2reactversion: 17.0.2react-domversion (if applicable): 17.0.2react-test-rendererversion (if applicable):nodeversion: 16npm(oryarn) version: 8.5.0
Relevant code or config:
// custom hook
import {useMemo, useState} from 'react';
export const useRenderHookWithMemo = (nums: number[]) => {
const [isGreater, setIsGreater] = useState(false);
const numsGreaterThanFive = useMemo(() => {
const result: number[] = [];
for (const num of nums) {
if (num > 5) {
setIsGreater(true);
result.push(num);
}
}
return result;
}, [nums]);
return [isGreater, numsGreaterThanFive] as const;
};
// test
import {renderHook} from '@testing-library/react-hooks';
import {useRenderHookWithMemo} from './renderhook';
test('useRenderHookWithMemo', () => {
const {result} = renderHook(() =>
useRenderHookWithMemo([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
);
const [isGreater, nums] = result.current;
expect(isGreater).toBeTruthy();
expect(nums.length).toBe(5);
});What you did:
when run the test I am getting error message as Too many re-renders. React limits the number of renders to prevent an infinite loop.
What happened:
when run the test I am getting error message as Too many re-renders. React limits the number of renders to prevent an infinite loop.
Reproduction:
run the test as the code example above
Problem description:
The renderHook should support useMemo as part of custom hook implementation given it's quite common for the custom hook to have it.
Suggested solution:
The issue is not that useMemo is not working, it’s that the nums array being passed to the hook in the renderHook callback is a new reference every time it is called which triggered the memo dependencies to change which will call setIsGreater again which will trigger another render with a new nums reference, spiolnning forever in an infinite loop.
To fix, create the array outside of the fallback instead.