Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receiving error - Hooks can only be called inside of the body of a function component when implementing React Spring basic example

I have a next app. the code for the app itself (pages, static etc.) is in a folder in the repo. called frontend. The app. itself is served through an express server via another folder in the repo. called backend.

Firstly I'm not sure if having these two separated is best practice, but I personally like doing it that way. Both folders have their own respective package.json and package-lock.json files.

I am also running ApolloServer on the backend express server via the /graphql endpoint. The app. works fine until I try to implement a component with react hooks. Namely the very simple example provided by react-spring as shown below:

import { useSpring, animated } from 'react-spring'

function App() {
  const props = useSpring({ opacity: 1, from: { opacity: 0 } })
  return <animated.div style={props}>I will fade in</animated.div>
}

I have renamed this from App to SpringDemo and it is called simply in a page component like follows:

function Home() {
  return (
    <div>
      <SpringDemo />
    </div>
  )
}

export default Home

On serving my app via the express server in the backend folder I get the following error in the browser:

Invariant Violation: 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

You might have mismatching versions of React and the renderer (such as React DOM)

I don't believe this to be the case, from my respective package.json files:

frontend/package.json

    "react": "^16.8.5",
    "react-apollo": "^2.5.2",
    "react-dom": "^16.8.5",

backend/package.json

    "react": "^16.8.5",
    "react-dom": "^16.8.5",

All versions seem to match at the latest 16.8.5.

You might be breaking the Rules of Hooks

Not likely with a copy pasted example from the react-spring docs.

You might have more than one copy of React in the same app

I don't believe I do, from my package.json listed above but I'm not sure. I read this https://github.com/facebook/react/issues/14823 issue, which then pointed me to this https://github.com/apollographql/react-apollo/issues/2792 but I can't be sure that this is the cause. Looking at the package-lock.json file doesn't elucidate (at least to me) if I am indeed running a different version of react/react-dom via react-apollo.

Checking the package.json on the react-apollo repo. here: https://github.com/apollographql/react-apollo/blob/master/package.json suggests that they're running the same version of react and react-dom, though different to my version of react and react-dom as listed above:

react-apollo/package.json

    "react": "16.8.4",
"react-dom": "16.8.4",

I also don't know if this aligns with my version of react-apollo, or indeed if this is the cause of this problem.

How can I solve this problem and figure out if I am indeed running multiple copies of react/react-dom? This hasn't been a problem for me with anything else react based.

EDIT:

To hopefully help I've created gists of my respective package.json and package-lock.json files:

frontend/package.json - https://gist.github.com/benlester/c7d82d7ad46cae9b8972284baba003a6

frontend/package-lock.json - https://gist.github.com/benlester/8f85b3fa290e67445ee0b2df365d8307

backend/package.json - https://gist.github.com/benlester/0c8004bdbb5b87c50734ba8044c35cee

backend/package-lock.json - https://gist.github.com/benlester/29f7a25f2ee633a13bdbdcee28270ddf

npm ls react - frontend

[email protected] [directory]
└── [email protected]

npm ls react - backend is the same as above.

like image 945
BML91 Avatar asked Oct 17 '22 05:10

BML91


1 Answers

I managed to fix this by changing the structure of the project.

Instead of having a separate package.json and package-lock.json in each of the frontend and backend folders I now have a single package.json and package-lock.json in the root folder (along with a single node_modules folder).

I don't know why this fixes the problem, as outlined in my question above all of my react and react-dom versions seemed to align with one another and I was using hooks correctly.

I also don't particularly love this solution as it forces me (at least with a single repo.) to use a single source for frontend and backend dependencies.

If anyone knows of a better way of managing frontend/backend mixed deps. I'm all ears in the comments.

like image 190
BML91 Avatar answered Oct 20 '22 06:10

BML91