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

[Bug] Different behaviour of context provider between yarn classic and yarn 4.3.x #441

Open
LorinRenodeyn opened this issue Jul 5, 2024 · 3 comments
Labels
bug Something isn't working needs more info Item needs further input from the creator

Comments

@LorinRenodeyn
Copy link

Description

I'm not 100% sure the issue is specific to this library or a react issue, but given the information I have at the moment it seems to point here.

I'm working on an NX monorepo project with a componentlibrary (and a few other libs) and 2 gatsby based websites.
The gatsby project is running Webpack 5 and Gatsby 5.12. In the componentlibrary I created a component that makes use of the map, advancedmarker components and library hooks. In the component library's storybook and in the website project that consumes the library, I placed the in the root with the other providers. This with the aim to have the context available to all components (many levels deep)

The package manager for the project is Yarn (Classic; v1.22.22).
Today I tried to upgrade the yarn version to the lasest berry (v4.3) release.

After changing the yarn version and reinstalling the packages.
My component using the map threw an error: " can only be used inside an component."
Trying to render a map as a direct child of the provider works fine, the one many levels deep does not.
yarn node-linker for 4.3 set to node-modules for compatibility

Reverting the yarn to classic version made the error disappear.
Haven't gone through the whole site, but so far this seems to be the only component / usecase having issues.

Steps to Reproduce

Setup NX project with

  • Gatsby 5 based website connecting to graphql that consumes component library in the same project
  • Component library using typescript (.ts and .tsx files) that gets built using rollup ("@nx/rollup": "19.1.0") & babel ("@babel/core": "^7.19.6")

yarn nodeLinker set to node-modules in yarnrc.yml

Terminal command: yarn set version berry; rm -rf node_modules; yarn install; yarn clean; yarn develop
(yarn clean and yarn develop execute gatsby clean and gatsby develop respectively)
Result: no errors in terminal, but opening the page with the component results in Unhandled Runtime Error message " can only be used inside an component." popup from gatsby + error boundary triggered & log in console.

Terminate the develop process in terminal and run yarn set version classic; rm -rf node_modules; yarn install; yarn clean; yarn develop
Result: everything works as intended, no error messages.

Nothing else changed apart from the yarn version and reinstalling packages between the 2 runs.

Environment

  • Library version: @vis.gl/react-google-maps@^1.1.0
  • Google maps version: weekly (no specific version passed to the APIProvider)
  • Browser and Version: Firefox 127.0.2 & Chrome 126.0.6478.127 (ARM 64)
  • OS: macOS Sonoma 14.5
  • yarn versions: 1.22.22 & 4.3.x
  • yarn nodeLinker for 4.3 set to node-modules for compatibility

Logs

helpers.js:124 Uncaught Error: <Map> can only be used inside an <ApiProvider> component.
    at Map (index.modern.mjs:847:11)
    at renderWithHooks (react-dom.development.js:15486:18)
    at mountIndeterminateComponent (react-dom.development.js:20098:13)
    at beginWork (react-dom.development.js:21621:16)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4164:14)
    at HTMLUnknownElement.sentryWrapped (helpers.js:102:17)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16)
    at invokeGuardedCallback (react-dom.development.js:4277:31)
    at beginWork$1 (react-dom.development.js:27485:7)
    at performUnitOfWork (react-dom.development.js:26591:12)
    at workLoopSync (react-dom.development.js:26500:5)
    at renderRootSync (react-dom.development.js:26468:7)
    at recoverFromConcurrentError (react-dom.development.js:25884:20)
    at performConcurrentWorkOnRoot (react-dom.development.js:25784:22)
    at workLoop (scheduler.development.js:266:34)
    at flushWork (scheduler.development.js:239:14)
    at MessagePort.performWorkUntilDeadline (scheduler.development.js:533:21)


head-export-handler-for-browser.js:72 The above error occurred in the <Map> component:

    at Map (webpack-internal:///../../node_modules/@vis.gl/react-google-maps/dist/index.modern.mjs:839:5)
    at InteractiveMap (webpack-internal:///../../libs/ui-babel/src/lib/modules/DealerOverviewModule/InteractiveMap/InteractiveMap.tsx:52:5)
    at ErrorBoundary (webpack-internal:///../../libs/ui-babel/src/lib/components/ErrorBoundary/ErrorBoundary.tsx:20:30)
    at div
    at section
    at DealerOverviewModule (webpack-internal:///../../libs/ui-babel/src/lib/modules/DealerOverviewModule/DealerOverviewModule.tsx:89:5)
    at ErrorBoundary (webpack-internal:///../../libs/ui-babel/src/lib/components/ErrorBoundary/ErrorBoundary.tsx:20:30)
    at PageItems (webpack-internal:///./src/ui-lib/components/Modules/PageItems/index.tsx:16:3)
    at BasicPage (webpack-internal:///./src/ui-lib/components/templates/BasicPage/BasicPage.tsx:44:3)
    at div
    at APIProvider (webpack-internal:///../../node_modules/@vis.gl/react-google-maps/dist/index.umd.js:537:26)
    at main
    at O (webpack-internal:///../../node_modules/styled-components/dist/styled-components.browser.esm.js:32:23383)
    at div
    at render
    at O (webpack-internal:///../../node_modules/styled-components/dist/styled-components.browser.esm.js:32:23383)
    at div
    at render
    at O (webpack-internal:///../../node_modules/styled-components/dist/styled-components.browser.esm.js:32:23383)
    at MainLayout (webpack-internal:///./src/ui-lib/components/Layout/MainLayout.tsx:78:3)
    at eval (webpack-internal:///../../node_modules/styled-components/dist/styled-components.browser.esm.js:32:28363)
    at ErrorBoundary (webpack-internal:///../../libs/ui-babel/src/lib/components/ErrorBoundary/ErrorBoundary.tsx:20:30)
    at Layout (webpack-internal:///./src/components/layout/index.tsx:363:3)
    at G (webpack-internal:///../../node_modules/@gatsbyjs/reach-router/dist/index.modern.mjs:36:9074)
    at BasicPage (webpack-internal:///./src/templates/BasicPage.tsx?export=default:42:3)
    at nt (webpack-internal:///../../node_modules/styled-components/dist/styled-components.browser.esm.js:32:20177)
    at IntlProvider (webpack-internal:///../../node_modules/react-intl/lib/src/components/provider.js:39:47)
    at PageWrapper (webpack-internal:///./src/ui-lib/components/Layout/PageWrapper.tsx:26:3)
    at ErrorBoundary (webpack-internal:///../../libs/ui-babel/src/lib/components/ErrorBoundary/ErrorBoundary.tsx:20:30)
    at PageRenderer (webpack-internal:///./.cache/page-renderer.js:22:47)
    at PageQueryStore (webpack-internal:///./.cache/query-result-store.js:24:5)
    at RouteHandler
    at div
    at re (webpack-internal:///../../node_modules/@gatsbyjs/reach-router/dist/index.modern.mjs:36:9865)
    at ee (webpack-internal:///../../node_modules/@gatsbyjs/reach-router/dist/index.modern.mjs:36:9680)
    at ae (webpack-internal:///../../node_modules/@gatsbyjs/reach-router/dist/index.modern.mjs:36:10957)
    at oe (webpack-internal:///../../node_modules/@gatsbyjs/reach-router/dist/index.modern.mjs:36:10831)
    at ScrollHandler (webpack-internal:///../../node_modules/gatsby-react-router-scroll/scroll-handler.js:23:35)
    at RouteUpdates (webpack-internal:///./.cache/navigation.js:227:5)
    at EnsureResources (webpack-internal:///./.cache/ensure-resources.js:17:5)
    at LocationHandler (webpack-internal:///./.cache/root.js:39:1)
    at eval (webpack-internal:///../../node_modules/@gatsbyjs/reach-router/dist/index.modern.mjs:36:8283)
    at F (webpack-internal:///../../node_modules/@gatsbyjs/reach-router/dist/index.modern.mjs:36:7181)
    at H (webpack-internal:///../../node_modules/@gatsbyjs/reach-router/dist/index.modern.mjs:36:7483)
    at WithErrorBoundary()
    at G (webpack-internal:///../../node_modules/@gatsbyjs/reach-router/dist/index.modern.mjs:36:9074)
    at Root
    at Ge (webpack-internal:///../../node_modules/styled-components/dist/styled-components.browser.esm.js:32:15933)
    at StaticQueryStore (webpack-internal:///./.cache/query-result-store.js:97:5)
    at SliceDataStore (webpack-internal:///./.cache/query-result-store.js:135:5)
    at ErrorBoundary (webpack-internal:///./.cache/fast-refresh-overlay/components/error-boundary.js:14:5)
    at DevOverlay (webpack-internal:///./.cache/fast-refresh-overlay/index.js:112:3)
    at RootWrappedWithOverlayAndProvider
    at App (webpack-internal:///./.cache/app.js:134:50)

React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
@LorinRenodeyn LorinRenodeyn added the bug Something isn't working label Jul 5, 2024
@usefulthink
Copy link
Collaborator

I have to admit that I don't know how gatsby works and how it might relate to a newer version of yarn.
To me this sounds like it has to have something to do with server-side-rendering or similar.

The main error-message ("<Map> can only be used inside an <ApiProvider> component."), will only happen when the APIProvider, or rather its context can't be found:

const context = useContext(APIProviderContext);
const loadingStatus = useApiLoadingStatus();
if (!context) {
throw new Error(
'<Map> can only be used inside an <ApiProvider> component.'
);
}

Assuming that the components are in the correct hierarchy, there has to something in the way the application is bundled (maybe multiple instances of the react-google-maps library?) or executed (maybe the Context-provider isn't rendered in the client-side code or something like that?)

In order for us to help you debug this, there has to be something where we can see this issue happening. This should ideally be reduced to the core of the issue in a format that I can just checkout and run.

@usefulthink usefulthink added the needs more info Item needs further input from the creator label Aug 1, 2024
@LorinRenodeyn
Copy link
Author

Thank you for taking the time to reply 🙂 I completely get your point of view. Unfortunately this is from a project I inherited that already went through several package updates before landing in my lap and I am not sure I could recreate the whole setup accurately to provide a proper reproduction repo. Nor do I have the time, sadly. That's why I tried to provide as many details as possible.

With the exact same codebase, component hierarchy, package versions and only different yarn versions the error popped up to my surprise. I'd guess the package resolution might be a factor? Perhaps a different (sub / peer) dependency being resolved somewhere on the newer yarn? This package was the only one throwing issues as far as I could tell.

@usefulthink
Copy link
Collaborator

Yeah, that's actually the only thing I can imagine right now where a different version of a package manager would have such an impact.
I had this a couple of times in other projects and those issues are notoriously hard to debug.

When multiple instances of the @vis.gl/react-google-maps packages end up being bundled into your application, there could be a situation where the APIProvider is created from one instance A (e.g. ./node_modules/@vis.gl/react-google-maps/dist/index.modern.js) and the Map component from another instance B (e.g. ./node_modules/some-component/node_modules/@vis.gl/react-google-maps/dist/index.modern.js). The map component would then load APIProviderContext from the same package and can't find a context created from that APIProvider (since A.APIProvider !== B.APIProvider). The same can also happen if your bundler produces multiple bundles and there are multiple instances of the very same package in different bundles.

You can check this with a bundle analyzer or see if there are multiple instances of the package in your node_modules (e.g. find ./node_modules -type d -path '*/@vis.gl/react-google-maps').

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs more info Item needs further input from the creator
Projects
None yet
Development

No branches or pull requests

2 participants