[renderHook] rerender with new props, new props are not consumed
alextrastero opened this issue · 9 comments
Passing new props to rerender doesn't work, please let me know if i'm doing anything wrong, thx
package.json
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
hook
export const useTriggerFocus = ({ condition = true, ref }: any): null => {
console.log(condition);
useEffect(() => {
const element = ref.current;
if (condition && element) {
element?.focus();
}
}, [ref, condition]);
return null;
};test
it('triggers a change', () => {
const condition = false;
const focus = vi.fn();
const ref = {
current: {
focus,
},
};
const { rerender } = renderHook(() => useTriggerFocus({ condition, ref }));
rerender({ condition: true, ref: undefined });
rerender();
rerender();
rerender();
});
});console
false
false
false
false
false
Care needed to ensure that your renderHook is configured such that it knows what to do with the new props you pass into the rerender call.
E.g. something along the lines of (not tested)…
it('triggers a change', () => {
const initialProps = {
condition: false,
ref: {
current: {
focus: vi.fn(),
},
},
};
const { rerender } = renderHook(({ condition, ref }) => useTriggerFocus({ condition, ref }), { initialProps });
rerender({ condition: true, ref: undefined });
});
});See the docs https://testing-library.com/docs/react-testing-library/api#rerender-1 for the syntax on how to make sure new props are used. Here I’ve also made use of the initialProps option https://testing-library.com/docs/react-testing-library/api#renderhook-options-initialprops.
At the moment your props passed to the rerender and being ignored as the renderHook callback is hardcoded to use those you defined at the beginning of your test.
P.S. your future queries for React Testing Library may be better placed in https://github.com/testing-library/react-testing-library or the discord than here as this is the Dom Testing Library repo! 🙃
P.P.S. take care when using a ref with useEffect - in a lot of use cases it doesn’t necessarily work, see https://epicreact.dev/why-you-shouldnt-put-refs-in-a-dependency-array/
This seems like a React Hooks Testing Library issue, I'm transferring this issue to the correct repository.
Thanks @timdeschryver , do you have a link for that?
@alextrastero you don't have to take any action, we've already transferred it to the correct repository.
You can find it here, https://github.com/testing-library/react-hooks-testing-library
Hey, sorry I missed the notification that this one was transferred here.
Sorry to play ping pong again with your issue, but can you confirm if you are using renderHook from @testing-library/react-hooks (pre React 18, this repo) or @testing-library/react (React 18, RTL repo).
If it’s the latter, I’ll transfer it to the RTL repo.
Edit: quickly looking at the issue as if it was for our version, I’d say the solution presented by @cmorten above is correct.
That worked for me:
const { rerender } = renderHook(useOverview, { initialProps });
Update: Ah I was too slow, as you’ve posted!
The intended pattern is:
const { result, rerender } = renderHook((props = {}) => useMyHook(props), {
initialProps,
});
expect(result.current).toEqual(firstResult);
rerender(newProps);
expect(result.current).toEqual(secondResult)There should be no need to workaround - the key is to not hardcode the initialProps being passed to your hook, but instead allow props to be passed to the renderHook callback so passing values into rerender works as expected.
See the example in https://testing-library.com/docs/react-testing-library/api/#renderhook-options-initialprops, though appreciate it perhaps isn’t the most clear as the “hook” in the example is the identity function of reflecting the props back rather than something explicitly use* as most folks will implement.
Thanks, @cmorten.