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

dynamic imported React.lazy component using hooks throws 'Invalid hook call' #745

Closed
li-yifei opened this issue Jul 14, 2020 · 8 comments
Closed

Comments

@li-yifei
Copy link

li-yifei commented Jul 14, 2020

  • @testing-library/react version: 10.4.6
  • Testing Framework and version: jest 26.1.0
  • DOM Environment: jest default jsdom

Relevant code or config:

# lazy-component.js
export default () => {
  const [value] = React.useState('I am lazy')
  return <div>{value}</div>
}
# test
const LazyComponent = React.lazy(() => import('../lazy-component'))
test('renders lazy', async () => {
  // this is how you test a component that needs a suspense component
  // just render it with your own suspense!
  render(
    <React.Suspense fallback="test loading">
      <LazyComponent />
    </React.Suspense>,
  )
  const lazyElement = await screen.findByText(/i am lazy/i)
  expect(lazyElement).toBeInTheDocument()
})

What you did:

Tried to render the whole with some lazy loaded components which using hooks.

What happened:

It throws

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
...

error when I call query methods from the render result or screen.

Reproduction:

There's a csb sample based on https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples

https://codesandbox.io/s/throbbing-lake-op237?file=/src/lazy-component.js

Problem description:

Can't test high level componets including React.lazy children

Suggested solution:

@li-yifei li-yifei changed the title dynamic imported React.lazy functional component throws 'Invalid hook call' dynamic imported React.lazy component using hooks throws 'Invalid hook call' Jul 14, 2020
@eps1lon
Copy link
Member

eps1lon commented Jul 14, 2020

It's also throwing Unable to find an element which might cascade into unhelpful errors from React. Could you fix the missing element errors first? Also: Can you reproduce this locally or only in codesandbox?

@MatanBobi
Copy link
Member

MatanBobi commented Jul 14, 2020

Hi @li-yifei, I tried to reproduce this in a new CRA and this doesn't reproduce, so following @eps1lon, can you reproduce this locally?
Another thing, I think that the @testing-library/react version you wrote is wrong, version 5 is from the beginning of 2019, I'm not even sure we had 5.11.0 version.

@li-yifei
Copy link
Author

li-yifei commented Jul 14, 2020

Hello @MatanBobi

Hi @li-yifei, I tried to reproduce this in a new CRA and this doesn't reproduce, so following @eps1lon, can you reproduce this locally?

Sure, I'm trying to do that. Actually it first happened in my work project.

Another thing, I think that the @testing-library/react version you wrote is wrong, version 5 is from the beginning of 2019, I'm not even sure we had 5.11.0 version.

Sorry, it should be 10.4.5. I copied the version of @testing-library/jest-dom accidently.

@li-yifei
Copy link
Author

@MatanBobi
The CRA project ran well but it's using @testing-library/react ^9.3.2

"dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-scripts": "3.4.1"
  }

After I upgraded to 10.4.6 the findByText call throwed TypeError: MutationObserver is not a constructor
Perhaps I should eject and install the same dependencies as my own project then run the test again.

@MatanBobi
Copy link
Member

You're right, that was my bad :) I upgraded and it still passed.
Just so you'll know:
No need to eject, this is a known issue with CRA.
The MutationObserver is not a constructor error is because jsdom 14 doesn't have MutationObserver.
I followed the steps to fix here and this test passed with CRA and latest @testing-library/react version.

@li-yifei
Copy link
Author

@MatanBobi
Finally I figured out that I had misused the

 beforeEach(() => {
    jest.resetModules()
  })

in my project, which probably caused 3. You might have more than one copy of React in the same app violation.
Sorry for bothering you. I'll close it.

@MatanBobi
Copy link
Member

@li-yifei
this still doesn't explain why it was reproduced in https://codesandbox.io/s/throbbing-lake-op237?file=/src/lazy-component.js ? Or it does and I missed something..

@trainiac
Copy link

trainiac commented Mar 28, 2023

For me the issue was resetModules: true in our jest config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants