Recoil
Recoil copied to clipboard
Recoil error when using yarn link and next.js with expo-next-adapter
Hello,
so I'm developing a Next.js app that uses my own library of react-native-expo components. To use those components, I've installed an expo-next adapter (https://www.npmjs.com/package/@expo/next-adapter).
Everything works great as long as I use the published version of my library in package.json. It is also ok when I use npm pack command to create a local .tgz file that contains my library. However, having to create a package and reinstall it everytime when I make the slightest change in my lib is a bit cumbersome - therefore I decided to use yarn link command to create a link between my next.js app and the library.
So this is my file structure: .. app-that-uses-the-library the-library
And I do this:
- I go to the-library folder and I do 'yarn link'
- I go to the app-that-uses-the-library and I do 'yarn link the-library'
- I also get into node_modules/react and node_modules/react-dom of my app-that-uses-the-library and do 'yarn link' in both of them.
- Then I go to the-library folder and do 'yarn link react' and 'yarn link react-dom' to make sure there is just one copy of React running (it is a common problem with linking local dependencies: https://stackoverflow.com/questions/56663785/invalid-hook-call-hooks-can-only-be-called-inside-of-the-body-of-a-function-com - here it is explained in a comment by theVoogie).
- Last, I run my app.
Unfortunately, about one second after I see some components rendered, the app crashes with the "Error: This component must be used inside a <RecoilRoot> component.".
Of course, I checked if that's true - but it is not - RecoilRoot is right on top of my tree, in _app.js:
function CustomApp({ Component, pageProps }: AppProps) { return ( <RecoilRoot> <AppWrapper> <Component {...pageProps} /> </AppWrapper> </RecoilRoot> ) }
Also, as I've mentioned before, this problem does not occur if the package is published or in a tarball - the problem seems to be connected to yarn link somehow.
I also tried this workaround mentioned by @jerrygreen on 5 Mar 2020 - he essentially just does the same thing but in a reverse direction.
The other thing I tried is to also do:
- Go to app-that-uses-library/node_modules/recoil then 'yarn link'.
- Then go to my library and do 'yarn link recoil'
- This actually removes the above error, however, another one comes up, specifically:
hooks can only be called inside the body of a function component
(which is supposed to be fixed by the sequence with linking react and react-dom I described in the beginning).
Any chance that anyone has ever faced this problem or possibly found a solution? I know I can dispose of yarn link and just use the tarball to develop locally, but I would prefer to use it as it allows for much faster development.
I use: Recoil: 0.5.2 Next: 10.2.1 React & React-dom: 17.0.1
Thanks in advance
Which yarn version are you using? In yarn 3, there is the "portal" protocol; maybe you should try that out. Linking a library, I do something like that in section "resolutions" in package.json. Not sure if the "resolutions" sections in Yarn 1.
Note the * (absolute path to the recoil folder, dependencies for recoil has to be installed, and the project has to be compiled)
"resolutions": {
"recoil": "portal:/Users/file-tree-abs-path-of/Recoil", *
"react": "portal:/Users/file-tree-abs-path-of/Recoil/node_modules/react",
"react-dom": "portal:/Users/file-tree-abs-path-of/Recoil/node_modules/react-dom"
},
Do something like that after yarn 3 is installed in your project, but before installing the dependencies in you project. Change the .yarnrc.yml file generated by Yarn 3
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-berry.cjs
I also have a nextJs project with Recoil and a similar yarn setup; the above should only be for local testing. The overall handling of yarn and linking specifically is tricky and requires some trial and error. I hope that helps.
Thanks, @gurkerl83 !
If anyone has that problem - I have actually found a different, working solution today: https://github.com/wclr/yalc
yalc acts as very simple local repository for your locally developed packages that you want to share across your local environment.
This is easy to setup (took like 5 minutes) and works perfectly. It is also capable of pushing changes to all the apps that use your local package.
I will leave this open (to the consideration of moderators), just in case anyone has this problem and above solution is for any reason not good for them.
I have a very similar issue in a nextjs app. But I am just using npm, not yarn. Here is the recoil stack trace:
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://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
at resolveDispatcher (/home/luksd/Repos/occasionally-for-business/node_modules/react/cjs/react.development.js:1476:13)
at useContext (/home/luksd/Repos/occasionally-for-business/node_modules/react/cjs/react.development.js:1484:20)
at useStoreRef (/home/luksd/Repos/occasionally-for-business/node_modules/recoil/cjs/recoil.js:4069:27)
at RecoilRoot (/home/luksd/Repos/occasionally-for-business/node_modules/recoil/cjs/recoil.js:4442:28)
Anyone resolve this? getting the same