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

Redux Toolkit Query 2.0 Beta Uncaught Error: could not find react-redux context value #2020

Closed
1 task done
jonaldinger opened this issue Jun 2, 2023 · 25 comments
Closed
1 task done

Comments

@jonaldinger
Copy link

What version of React, ReactDOM/React Native, Redux, and React Redux are you using?

  • React: 18.2.0
  • ReactDOM/React Native: 18.2.0
  • Redux: 5.0.0-beta.0
  • Redux Toolkit: 2.0.0-beta.0
  • React Redux: 8.0.7

What is the current behavior?

When upgrading from react-redux 8.0.5 to 8.0.7, along side of Redux Toolkit 2.0.0-beta.0 + Redux 5.0.0-beta.0, my application code throws an error when using an RTK Query hook:

Uncaught Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>
    at useReduxContext (useReduxContext.js:24:11)
    at useStore2 (useStore.js:17:9)
    at useDispatch2 (useDispatch.js:14:19)
    at useQuerySubscription (buildHooks.ts:689:24)
    at useQuery (buildHooks.ts:964:42)
    at RequireAuthentication (RequireAuthentication.tsx:34:7)

The application code is wrapped in a Provider and has been functioning normally for months with the Redux Toolkit alphas, and is also functioning normally with the just-released Redux Toolkit beta. It is only when I upgrade to react-redux 8.0.7 that the error is thrown. When I downgrade to react-redux 8.0.5, without modifying any other dependencies, the error is not thrown.

Interestingly, useSelector(), which I would assume is accessing the same exact context from the provider, works fine. But useGet*Query() from RTK Query throws. Final note, I am using Yarn PnP and Yarn Workspaces.

What is the expected behavior?

No error should be thrown, as the component is wrapped in a provider.

Which browser and OS are affected by this issue?

Chrome 113 on macOS Ventura

Did this work in previous versions of React Redux?

  • Yes
@EskiMojo14
Copy link
Collaborator

My assumption is that you're using a custom context, and providing the hooks to the react API module.

One of the breaking changes made in RTK's alphas/betas (I'm unsure which one) is that the signature of reactHooksModule changed: reduxjs/redux-toolkit#3400

reactHooksModule({
    hooks: {
      useDispatch: createDispatchHook(MyContext),
      useSelector: createSelectorHook(MyContext),
      useStore: createStoreHook(MyContext),
    },
  })

This is likely the main thing that's causing your issue.

@jonaldinger
Copy link
Author

Thanks for the reply @EskiMojo14. I'm not using custom context, just the standard createApi() which is added to the reducer object in a standard configureStore(). The weird part here is that my application code works totally fine with all versions of the RTK alphas/betas. It only breaks when upgrading from react-redux 8.0.5 to 8.0.7 (along side of either RTK 2.0.0-alpha.5 or 2.0.0-beta.0 - I haven't tested with other versions). And there don't seem to be many actual material changes in those react-redux updates between 8.0.5 and 8.0.7 - mostly documentation. One exception is a rather large update to the lockfile, which could possibly be impacting dependencies?

@EskiMojo14
Copy link
Collaborator

it's possible you have multiple versions of react-redux - try running npm ls react-redux

@jonaldinger
Copy link
Author

jonaldinger commented Jun 2, 2023

I'm using Yarn PnP with Workspaces, but the following is equivalent. I also verified I have single versions of React, ReactDOM, Redux, and Redux Toolkit.

Screenshot 2023-06-02 at 6 03 22 PM

@EskiMojo14
Copy link
Collaborator

interesting, that's really odd - would you be able to make a recreation in codesandbox?

@markerikson
Copy link
Contributor

markerikson commented Jun 2, 2023

@jonaldinger : the lockfile updates were just me updating the website folder from Docusaurus 2.0-beta to 2.4, no runtime or devdep changes.

I would be very curious to see a repro of this.

Or, even better, could you make a Replay recording and share that here?

https://replay.io/record-bugs

@jonaldinger
Copy link
Author

Thanks so much for the responsiveness @EskiMojo14 and @markerikson. I'm about to sign off for the weekend, but will try to create something useful to help debug next week. FYI this isn't actively blocking, everything works 100% if I stay on react-redux 8.0.5 even when I update everything else to latest including alpha and beta versions. I opened the issue just as a proactive measure to sniff out a potential issue with the beta.

@phryneas
Copy link
Member

phryneas commented Jun 3, 2023

You actually have four different instances of the same version of react-redux installed here - see that hash in the square bracket after the version number. Those four versions will not be able to interact with each other - you'll have to play around with that to get them to the same instance.

@jonaldinger
Copy link
Author

@phryneas great spotting. That seems very likely to be the issue, as the working state with 8.0.5 has a common hash across all workspaces:

hash

I'm not sure what's driving that change with the upgrade, but let's assume it's on my end. I'll do some tinkering. Thank you!

@shermify
Copy link

shermify commented Jun 19, 2023

I'm actually running into this same bug with redux-toolkit 1.9.5 and I don't think there is an easy workaround.

I could be wrong, but my guess is that adding redux-toolkit 2.0-beta to react-redux peer dependencies has broken yarn pnp due to the circular peer dependency between the two packages. This forces yarn to create virtual instances of both packages in every workspace because it cannot guarantee the dependency tree will be the same across workspaces. As you can see below, the hashes in those screenshots indicate dependency trees, not duplicate packages. If react-redux requires a singleton package, this is going to be a problem for anyone using yarn workspaces.

Screenshot from 2023-06-19 14-44-44

@markerikson
Copy link
Contributor

markerikson commented Jun 19, 2023

That... sounds horrifying.

I have no idea what to do about that.

I guess I could remove RTK from the React-Redux peer deps?

@shermify
Copy link

Perhaps someone more knowledgeable about yarn can chime in to make sure I'm not talking out of my backside, but I made a simple repro here

https://github.com/shermify/react-redux-repro

It's a common pattern for workspaces to share a package that exports RTK slices and apis. Works with react-redux 8.0.5 but not 8.1.0 due to the above issue.

@phryneas
Copy link
Member

We can probably get rid of that singleton going forward, but that will only fix future versions.

@jonaldinger
Copy link
Author

@shermify thank you for the info and repro. I did some more local testing over the past few days and am seeing the exact same thing as you (single installed dependencies, but multiple virtual instances of both RTK and react-redux). I tried tweaking lots of things, but always got the same outcome. I think your theory sounds correct:

I also have the same feature use case - a monorepo (Yarn Workspaces) that has multiple apps that connect to common APIs. The core workspace defines the shared slices, which are then imported and consumed by multiple other app workspaces. This setup has been working great up until now (and I've been using the RTK alpha for many months).

It feels reasonable that the peer dependency would be declared in either RTK or react-redux, but not both. And I'm not an expert here, but it actually seems to make more sense to remove the peer dependency from RTK instead, since that's the "larger/core/foundational" library (it's my understanding that you can technically use RTK without react-redux, but you can't use react-redux without react and redux or RTK). For example:

  • react does not declare react-dom as a peer dependency (but react-dom does declare react as a peer dependancy)
  • redux does not declare react-redux or @reduxjs/toolkit as peer dependencies
  • react-redux declares 6 optional peer dependencies. 5 of those optional peer dependencies do not list react-redux as their peer dependency. @reduxjs/toolkit is the only peer dependency in that list to have a circular peer dependency declared.

@markerikson @phryneas again appreciate the responsiveness and discussion!

@EskiMojo14
Copy link
Collaborator

EskiMojo14 commented Jun 19, 2023

the issue is that there are entry points in RTK (@reduxjs/toolkit/query/react already in 1.x, @reduxjs/toolkit/react added in 2.0) that directly use react-redux.
on the other hand, there is no code in react-redux that uses RTK. it depends on redux core types, but nothing from RTK itself.

as such i'd argue it'd make more sense for RTK to have the peer dep and react-redux not to

@markerikson
Copy link
Contributor

Yeah, I can try removing it from React-Redux

@jonaldinger
Copy link
Author

Ah ok, thanks for the context. At that point, if RTK 2.0 is now directly importing code from react-redux internally, would it make more sense for react-redux to become an actual dependency of RTK rather than an optional peerDependency? (feel free to say absolutely not - I don't know the larger considerations/implications there 😄).

@EskiMojo14
Copy link
Collaborator

it's an optional peer dependency because it's entirely possible to use RTK without react-redux - it's just the react specific entry points that would need it, basically

@shermify
Copy link

shermify commented Jun 19, 2023

FYI, if you list react-redux and redux-toolkit as peer dependencies in your shared library and remove them as direct deps, it should fix the issue because then it ensures the shared library is using the correct react-redux instance provided by each app. This is probably the right way to do it so long as react-redux requires a singleton package. It's definitely not obvious at first and will trip a lot of people up though. You have to make sure the last package in your dependency chain provides react-redux and redux-toolkit, and all the others pass them on as peer dependencies.

I'm not sure if removing redux-toolkit from react-redux peer dependencies alone will solve the issue because there were other changes to both package's dependencies that could cause branching. I think the reality is this pattern will be fragile as long as react-redux requires a singleton.

@phryneas
Copy link
Member

@shermify going forward, we should be able to solve that "singleton context item" problem with #2039.

@markerikson
Copy link
Contributor

I'll see if I can get out 8.1.1 tonight with the context fix and the peerDep removal

@markerikson
Copy link
Contributor

okay, 8.1.1 is out:

https://github.com/reduxjs/react-redux/releases/tag/v8.1.1

Please let us know if that fixes things!

@jonaldinger
Copy link
Author

@markerikson, the dependency hashes with v8.1.1, they're beautiful 🥲 Fixed for both RTK and react-redux. Oh and also all of the behavior is seeming back to normal. I clicked around a bunch in different apps and saw no occurrences of missing context. Thanks all! I even learned some new things through this.

react-redux-hashes

@shermify
Copy link

Works for me. Thanks for being on top of this so quickly!

@jonaldinger
Copy link
Author

Everything remains rock solid, so closing. Thanks again!

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

5 participants