React-redux: Store not passed via Provider to imported components in library projects with ver 6.0.0

Created on 17 Jan 2019  路  27Comments  路  Source: reduxjs/react-redux

This issue occurs in 6.0.0, and is not seen in 5.0.7.

In this case, the component library was created with create-react-library. That child project was pulled in as a dependency, and its containers and reducers referenced in the consuming project.

    "react": "^16.7.0",
    "react-dom": "^16.7.0",
    "react-redux": "^5.0.7", (^6.0.0 fails with 'store not found')
    "react-scripts": "2.1.3",
    "redux": "^4.0.1",
const store = createStore(
  someApp,
  applyMiddleware(
    thunkMiddleware
  )
)

ReactDOM.render(
    <Routes store={store} />, document.getElementById('root'));

const Routes = (props) => (
  <Provider {...props}>
    <Router history={hashHistory}>

Most helpful comment

I ejected the app, added an alias for react-redux like the snippet below and it works

alias: {
  // Support React Native Web
  // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
  'react-native': 'react-native-web',
  'react-redux': path.resolve('./node_modules/react-redux')
},

So I guess the problem is that for some reason it loads the wrong version of react-redux. I still haven't figured out where it finds it though. Both my-app and my-private-package use v6.0

All 27 comments

The description here is very unclear.

Please provide a project that reproduces the issue, and a more detailed description of exactly what you _expect_ to have happen, and what is _actually_ happening.

This is a bug tracker, not a support system. For usage questions, please use Stack Overflow or Reactiflux where there are a lot more people ready to help you out. Thanks!

This is a bug. Please read OP's text more closely. He is not asking for help.

The bug manifests itself if react-redux version 6 is used in a NPM module that exports some connected React component.
The NPM module itself has no redux store and provider, but when you import that module it says that the base component that is exported from the same module needs to be wrapped with a Provider component.

So it happens if react-redux is a peer dependency

This was a pain to track down. Version 5.0.7 does not manifest the above behavior.

@utajum : I asked for a project that reproduces the issue, but nothing has been provided. Without that, there's not much we can do.

Same issue here. I have a private npm package that exports a connected react component.
Using this connected component in another react app, I get the following error:

Uncaught Error: Could not find "store" in either the context or props of "Connect(AppBar)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(AppBar)"

It worked fine in version 5.1.1

Folks. PLEASE. PROVIDE. SOME PROJECTS. THAT REPRODUCE. THE ISSUE.

If you want us to investigate this, you need to make it as easy as possible to see what's going on ourselves and investigate.

I personally have a ton of other concerns on my plate right now that are taking precedence. _If_ someone can put together a repo or two that demonstrates the issue just by cloning and running it, then I _may_ have time to look at it. But right now, I don't have enough info to go on, and no one is providing the help I've requested.

In addition, trying to create a new standalone repro project often turns up the cause of the issue as you put the repro together, or demonstrates that the problem is due to a misconfiguration of some kind.

I've run into this as well, but figured it out as yarn link issue.
There is good explanation here (although it's about npm link) https://medium.com/@penx/managing-dependencies-in-a-node-package-so-that-they-are-compatible-with-npm-link-61befa5aaca7

tldr: linked package uses wrong instance of react-redux, so that there is nothing in context of that instance. Painful point is that this was not an issue with react-redux@5 (not visible at least)

@markerikson you are right.

I created a repo that demonstrates the issue:
https://github.com/gerhat/react-redux-could-not-find-store

Thanks a lot

@gerhat : one question off the top of my head: does this still occur when you do _not_ use npm link?

@markerikson I stand in awe! It doesn't occur!

The issue occurs for our applications regardless of whether the dependency is linked or imported from our repository. My component library, initially created using create-react-library, has been published to our internal Nexus repository. When other teams consume it, they see the error, and then I instruct them to change their local react-redux dependency to 5.0.7
If I have some time, I'll try to create an app that reproduces the issue.

@grunlowen2 : thanks.

Implementation-wise, the only relevant difference in this aspect between v5 and v6 is that we switched to using createContext to pass down the state and the store, and we rely on a singleton ReactReduxContext context instance as the default. What I'm generally seeing out of this is that somehow your applications are ending up in a situation where you are effectively importing two distinct versions of ReactReduxContext, so the different parts of the app aren't actually communicating with each other. This would generally seem to be related to your build setup in some way.

Interesting. The component library app is fairly complex, with much of it ported from an earlier version. I'll see if I can't recreate the issue (or not) in a entirely new setup.

https://github.com/utajum/react-redux-bug-repo

Note that this is a working version. To brake it upgrade react-redux in this package.json to version 6 and run npm run build

The main-project directory is a normal create-react-app project that imports the react-redux-bug package

@utajum : thanks. I'll ask a similar question as what I asked earlier: does this behavior still happen if you _don't_ use a file:../ package reference?

I ejected the app, added an alias for react-redux like the snippet below and it works

alias: {
  // Support React Native Web
  // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
  'react-native': 'react-native-web',
  'react-redux': path.resolve('./node_modules/react-redux')
},

So I guess the problem is that for some reason it loads the wrong version of react-redux. I still haven't figured out where it finds it though. Both my-app and my-private-package use v6.0

Further debugging showed that it doesn't load different versions. Both my-app and my-private-package load version 6.0. They just load it from different directory. Each package loads it from its respective node_modules directory.

Bottom line:

  • when my-private-package uses the parent's react-redux it works
  • when it uses its own react-redux it doesn't

@markerikson could it be that the singleton ReactReduxContext context instance is not shared despite the fact that the versions are the same?

@gerhat : yes, that's exactly what I was talking about. Each individual file is a separate module that is initialized once. So, if your lib effectively imports from react-redux-A/context.js, and your app imports from react-redux-B/context.js, those are two different files, and each will contain literal different context instances returned from React.createContext(). Therefore, the <Provider> and connected component won't be using the exact same instance, and they won't be talking to each other.

I ejected the app, added an alias for react-redux like the snippet below and it works

@gerhat it works until you have something like react-beautiful-dnd in your parent project - https://github.com/atlassian/react-beautiful-dnd/issues/1056

It fails because webpack alias forces react-beautiful-dnd to also use react-redux@6, so more fine grained module resolution override is required.

Another option is to manually put build artifact into parent's node_modules folder.

Both options are unhandy.

I faced an issue like this and I used this workaround.

Say you have 2 projects: my-app and my-lib. my-lib has react-redux as a peerDependency, but my-lib depends on other third-party packages which themselves depend on react-redux (ex: react-beautiful-dnd).

The problem I had when doing yarn link is that the my-lib is trying to use react-redux from its own node_modules not my-app's node_modules. So I had 2 different instances of react-redux.

Solution:

  • Before doing yarn link, remove from my-lib all dependencies which depend on react-redux. In other words, make sure you don't have any react-redux installed in your yarn.lock.
  • Do yarn link
  • Put back your dependencies in my-lib.

Like this my-lib will use the parent's react-redux.

I know it is a hack... But it will unblock you until you find a better solution.

I had the same problem. I just downgraded react-redux to 5.1.2

@vnosikov : the issue is likely with your build environment. I strongly recommend checking to see if you have multiple copies of react or react-redux being pulled in to your project.

@gerhat : one question off the top of my head: does this still occur when you do _not_ use npm link?

Works for me without npm link. Any idea what causes this? My workflow would be improved if npm link worked though. Any workarounds?

So guys @gerhat @markerikson how can I make the library points to the parent's react-redux I am trying npm link ./linkToParentApp/react-redux but it fails , any ideas?

@RehabHussein make sure you have the following alias in your webpack.conf:

resolve: {
  alias: {
    'react-redux': path.resolve('./node_modules/react-redux')
  },
},

In case you are using CRA, you will need to eject.

In case you are using CRA, you will need to eject.

@RehabHussein @gerhat You can also use customize-cra and add something like this to your config-overrides.js:

const path = require('path');
const {
    override,
    addWebpackAlias
} = require('customize-cra');

module.exports = function (config, env) {
    return Object.assign(config, override(
        addWebpackAlias({
            ['react-redux']: path.resolve('./node_modules/react-redux')
        })
    )(config, env))
}

This saves you from ejecting but you'll need to make little changes to your scripts in package.json (see customize-cra docs).

@gerhat actually I don't want to eject the project
@digitalbreed I can give this a try but wondering why npm link to react-redux doesn't work although it works with react ? any ideas guys ?

Was this page helpful?
0 / 5 - 0 ratings