I have a code snippet here from NextJS 13
export default function Members() {
// States
const [users, setUsers] = useState<MemberType[]>([]);
const [loading, setLoading] = useState(false);
const searchParams = useSearchParams();
// To refresh the page
const router = useRouter();
const inputRef = useRef<HTMLInputElement | null>(null);
// Function to fetch a book
const fetchBooks = async (userQuery: string | null) => {
if (!userQuery) {
const res = await fetch("/api/users/members", {
method: "GET",
headers: { "Content-Type": "application/json" },
});
const body: MemberType[] = await res.json();
return body;
}
const res = await fetch(`/api/users/members/${userQuery}`, {
method: "GET",
headers: { "Content-Type": "application/json" },
});
const body: MemberType[] = await res.json();
return body;
};
// Runs if the search parameters change
useEffect(() => {
setLoading(true);
const searched = searchParams.get("search");
console.log(searched);
fetchBooks(searched).then((users) => {
setUsers(users);
setLoading(false);
});
if (searched && inputRef.current) {
inputRef.current.value = searched;
}
}, [searchParams]);
//...
And I am testing the Members function using Jest.
In the test file I have this mock
jest.mock("next/navigation", () => ({
useRouter: () => ({
push: jest.fn(),
}),
useSearchParams: () => ({
get: jest.fn().mockReturnValue(''),
}),
}));
and this simple test
describe("Members page", () => {
it("should render the page correctly", async () => {
await act(async () => {
render(<Members />);
});
});
});
However, the test times out and it seems like that the useEffect hook is running infinitely. I suspect that it is something to do with the get function in the mock which triggers the useEffect hook again. I have been looking if there is anyway to change this mock?
2
Answers
You are returning a new object every time
useSearchParams
is calledDo this instead:
I believe it would be safer to just listen to the field changes that you really need, in your case
search
, especially when it’s a primitive string.