Closed jonaldinger closed 1 year ago
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: https://github.com/reduxjs/redux-toolkit/pull/3400
reactHooksModule({
hooks: {
useDispatch: createDispatchHook(MyContext),
useSelector: createSelectorHook(MyContext),
useStore: createStoreHook(MyContext),
},
})
This is likely the main thing that's causing your issue.
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?
it's possible you have multiple versions of react-redux - try running npm ls react-redux
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.
interesting, that's really odd - would you be able to make a recreation in codesandbox?
@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?
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.
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.
@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:
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!
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.
That... sounds horrifying.
I have no idea what to do about that.
I guess I could remove RTK from the React-Redux peer deps?
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.
We can probably get rid of that singleton going forward, but that will only fix future versions.
@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 dependenciesreact-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!
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
Yeah, I can try removing it from React-Redux
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 😄).
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
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.
@shermify going forward, we should be able to solve that "singleton context item" problem with #2039.
I'll see if I can get out 8.1.1 tonight with the context fix and the peerDep removal
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!
@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.
Works for me. Thanks for being on top of this so quickly!
Everything remains rock solid, so closing. Thanks again!
What version of React, ReactDOM/React Native, Redux, and React Redux are you using?
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:
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. ButuseGet*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?