Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rerender with a wrapper #1156

Open
lithin opened this issue Oct 6, 2022 · 1 comment
Open

Rerender with a wrapper #1156

lithin opened this issue Oct 6, 2022 · 1 comment
Assignees

Comments

@lithin
Copy link

lithin commented Oct 6, 2022

  • @testing-library/react version: 13.4.0
  • Testing Framework and version: jest @ 29.0.3
  • DOM Environment: jsdom @ 20.0.0

Relevant code or config:

// in test utils
const customRender = (
  ui: ReactElement,
  apolloMocks?: ApolloMocks,
  options?: Omit<RenderOptions, 'wrapper'>
) =>
  render(ui, {
    wrapper: () => ui, // this would include our providers wrapped around ui but this demonstrates the issue in a cleaner way
    ...options,
  });

// in test file

const Comp = ({ number }: { number: number }) => <p>{number}</p>;

it('check render', () => {
    const { rerender } = customRender(<Comp number={1} />);
    rerender(<Comp number={2} />);
    expect(screen.getByText('2')).toBeInTheDocument();
  });

What you did:

Rerendering a component that was originally rendered out with the wrapper option, combining two different guides in the docs.

What happened:

No props are updated. The component does rerender, however it does so with the "old" props. (So in the example above, the test fails because 1 is present instead of 2.)

Reproduction:

Happy to add this if necessary.

Problem description:

We can't actually re-render stuff :) The workaround we're using is to put the wrapper directly into the test but that sort of defeats having any wrapper to begin with.

Suggested solution:

Not sure how the internals work and why the wrapper would interfere with the props. I imagine we'd need to see why the props aren't being passed correctly and fix it on that level.

@eps1lon
Copy link
Member

eps1lon commented Oct 8, 2022

Note the

render(ui, {
    wrapper: () => ui,

This means that your wrapper will always render the initial element not the element given to rerender.

Remember that wrapper is treated as a normal React component. What happens internally is just normal React:

<Wrapper>
{element}
</Wrapper>

But in your example element will always be the initial ui.

What you want instead is

render(ui, {
    wrapper: (props) => props.children,

children will be what you give to render(children) and rerender(children).

I'll move this to the docs to add an example that highlights the importance of handling children.

@eps1lon eps1lon transferred this issue from testing-library/react-testing-library Oct 8, 2022
@eps1lon eps1lon self-assigned this Oct 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants