React-redux: ReactNative - Could not find "store"error after upgrading to 6.0.0 (from 5.1.1)

Created on 11 Dec 2018  路  52Comments  路  Source: reduxjs/react-redux

Do you want to request a _feature_ or report a _bug_?
_bug_

What is the current behavior?
I get an error:

Invariant Violation: Could not find "store" in the context of "Connect(Home)". Either wrap the root component in a , or pass a custom React context provider to and the corresponding React context consumer to Connect(Home) in connect options.

This error is located at:
in Connect(Home) (created by SceneView)
in SceneView (at createTabNavigator.js:39)
in RCTView (at View.js:45)
in AnimatedComponent (at BottomNavigation.js:576)
in RCTView (at View.js:45)
in AnimatedComponent (at BottomNavigation.js:561)
in RCTView (at View.js:45)
in RCTView (at View.js:45)
in BottomNavigation (created by Context.Consumer)
in ThemeProvider (created by Context.Consumer)
in withTheme(BottomNavigation) (at createMaterialBottomTabNavigator.js:51)
in BottomNavigationView (at createTabNavigator.js:197)
in NavigationView (created by Navigator)
in Navigator (created by SceneView)
in SceneView (at StackViewLayout.js:793)
in RCTView (at View.js:45)
in AnimatedComponent (at StackViewCard.js:69)
in RCTView (at View.js:45)
in AnimatedComponent (at screens.native.js:58)
in Screen (at StackViewCard.js:57)
in Card (at createPointerEventsContainer.js:27)
in Container (at StackViewLayout.js:858)
in RCTView (at View.js:45)
in ScreenContainer (at StackViewLayout.js:311)
in RCTView (at View.js:45)
in AnimatedComponent (at StackViewLayout.js:307)
in Handler (at StackViewLayout.js:300)
in StackViewLayout (at withOrientation.js:30)
in withOrientation (at StackView.js:79)
in RCTView (at View.js:45)
in Transitioner (at StackView.js:22)
in StackView (created by Navigator)
in Navigator (at createKeyboardAwareNavigator.js:12)
in KeyboardAwareNavigator (created by SceneView)
in SceneView (created by SwitchView)
in SwitchView (created by Navigator)
in Navigator (at createAppContainer.js:388)
in NavigationContainer (at App.js:57)
in WrappedRoot (created by NamespacesConsumerComponent)
in NamespacesConsumerComponent (created by WithMergedOptions)
in WithMergedOptions (created by Context.Consumer)
in WithMergedOptions(NamespacesConsumerComponent) (created by LoadNamespace)
in LoadNamespace (created by WithMergedOptions)
in WithMergedOptions (created by Context.Consumer)
in LoadNamespace(WrappedRoot) (at App.js:64)
in Provider (at App.js:46)
in I18nextProvider (at App.js:45)
in App (at renderApplication.js:34)
in RCTView (at View.js:45)
in RCTView (at View.js:45)
in AppContainer (at renderApplication.js:33)

renderWrappedComponent
index.bundle?platform=ios&dev=true&minify=false:171398:34
updateContextConsumer
index.bundle?platform=ios&dev=true&minify=false:16716:31
performUnitOfWork
index.bundle?platform=ios&dev=true&minify=false:19453:27
workLoop
index.bundle?platform=ios&dev=true&minify=false:19487:47
renderRoot
index.bundle?platform=ios&dev=true&minify=false:19558:21
performWorkOnRoot
index.bundle?platform=ios&dev=true&minify=false:20278:23
performWork
index.bundle?platform=ios&dev=true&minify=false:20205:30
performSyncWork
index.bundle?platform=ios&dev=true&minify=false:20181:20
requestWork
index.bundle?platform=ios&dev=true&minify=false:20060:26
scheduleWork
index.bundle?platform=ios&dev=true&minify=false:19932:22
enqueueSetState
index.bundle?platform=ios&dev=true&minify=false:14373:23
setState
index.bundle?platform=ios&dev=true&minify=false:5045:37

index.bundle?platform=ios&dev=true&minify=false:86047:26
tryCallOne
index.bundle?platform=ios&dev=true&minify=false:3044:16

index.bundle?platform=ios&dev=true&minify=false:3145:27
_callTimer
index.bundle?platform=ios&dev=true&minify=false:24010:17
_callImmediatesPass
index.bundle?platform=ios&dev=true&minify=false:24046:19
callImmediates
index.bundle?platform=ios&dev=true&minify=false:24265:33
__callImmediates
index.bundle?platform=ios&dev=true&minify=false:2439:35

index.bundle?platform=ios&dev=true&minify=false:2276:34
__guard
index.bundle?platform=ios&dev=true&minify=false:2422:15
flushedQueue
index.bundle?platform=ios&dev=true&minify=false:2275:21

What is the expected behavior?
It worked fine in 5.1.1

Which versions of Redux, and which browser and OS are affected by this issue? Did this work in previous versions of Redux?
React Native

Most helpful comment

After many hours I've found the silly error, my code was importing connect from 'react-redux/lib/connect/connect' instead of 'react-redux'.

All 52 comments

I have the same problem

Were you passing the store directly as a prop to a component, or are you using any additional libraries like connected-react-router ?

Directly as a prop

 render() {
    return (
        <I18nextProvider i18n={i18n}>
            <Provider store={store}>
                {this.getRequiredStack()}
            </Provider>
        </I18nextProvider>)
   }

What version of React and React Native are you using?

"react-native": "0.57.7"
"react": "16.6.1"

"react-native": "0.57.7"
"react": "16.6.1"

I use the same version as well

Same, but without React Native.

For anyone experiencing this issue, please provide a CodeSandbox or similar project that reproduces the issue. What I've seen since the release is that this is usually a misconfiguration in your application.

For those on RN, you can use Snack to demonstrate the problem.

And here's a _really_ simple example with 6.0 installed: https://snack.expo.io/@timdorr/react-redux-6

https://repl.it/repls/StrangeModernGraphs Hope it helps, I've never done this before. It's a micro-version of my repo Okulys Color Tests. I've added line 9 and 33 in Index.js after many tests, but not working. I'm missing something.

@Clebal: aha. It's because you're trying to define your own custom store context instance and passing that to <Provider store={store} context={StoreContext}>, but you're not passing that same context object to the connected component.

You shouldn't need to define a custom context object, except in exceedingly rare cases. Just do <Provider store={store}>.

Also, FYI, you can simplify the connect usage:

const mapDispatch = {
  attemptAddComparisonTest,
  cleanError,
}

export default connect(mapStateToProps, mapDispatch)(ComparisonTest)

See the React-Redux docs on using the "object shorthand" form of mapDispatch for more details.

Thanks for the advice, @markerikson. I've deleted context attribute from Provider, but the problem just moved from the server to the client, the error now appears in Chrome console:

captura de pantalla 2018-12-11 a las 21 06 32

I'm trying to reproduce that error in repl.it.

Can you use Codesandbox.io instead? I'm finding it impossible to get anything to output from that service. It's quite confusing.

After many hours I've found the silly error, my code was importing connect from 'react-redux/lib/connect/connect' instead of 'react-redux'.

Huh. I don't even know what that would do, exactly.

In any case, yeah, seems like a misconfiguration issue, as I expected.

I'm going to go ahead and close this thread.

If anyone else sees an error like this, _please_ create a small project that reproduces the problem before filing an issue.

It has problem on SwitchNavigator works fine on first stack doesn't work on second

@alexandrius : as I said, if you're having problems, please create a project that reproduces the issue. We can't do any investigating based on comments like that.

OK I found the issue:
I had wrong imports in every connected component
import connect from "react-redux/es/connect/connect";
instead of
import {connect} from "react-redux";

As I said, it sounds like pretty much every example of this that is popping up is an app misconfiguration issue.

@alexandrius, can you clarify why you had imports that looked like that? We've never suggested that pattern.

@markerikson I believe WebStorm imported this way

VS Code did the same bad job as WebStorm

Weird. Do they set up the imports the same way when used with React-Redux 5.x? Our library build setup didn't change between v5 and v6.

@timdorr, any idea why they're picking up the package definitions that way?

Nope. Maybe they're doing deeper package inspection. It's nothing we're doing, though.

@markerikson I'm noticing that when I import react-redux while using webpack with target:'node' It imports the react-redux/es/connect/connect file. (I put debugger;s in the files to see which one was accessed). I think it may have to do with the module config in the package.json, but I'm not certain.

I'm having the same error as the others, but even when forcing webpack to load the correct file using an alias, I get this problem while server side rendering calling React.renderToString

Like you, I had the same bug.
In my case, the reason was that we use company private npm modules.
Each module there was a dependency on redux and react-redux.
Version 5 worked fine with this structure,
but starting from version 6th,
the and connect()
should be imported from the same "node_modules/react-redux" folder.
When using "npm link moduleA" this error occurred.

Solution:
Import "react-redux" and "redux" from "node_modules"
only Once in one of your npm modules (for example in "moduleA").
All others projects should do:
import { Provider, connect } from 'moduleA/reactRedux';

Downgrading Redux from 4.0.1 to 3.0.1 solved an issue.

@helenkapatsa : that sounds extremely odd. The specific version of Redux shouldn't matter here. (Also, there's no reason you should be using Redux 3.0 at this point - the latest 3.x version is 3.7.2.)

I'm still hitting this issue with React Native 0.59.2. Besides downgrading Redux, did anyone find a solution to this?

When it comes to an educational project with existing education repo, sometimes copying all the dependencies version into my package.json and running 'npm install' helps, so that dependencies compatibility issue is resolved by somebody else.

I've noticed I only get this error in components that have been connected to Redux store that are nested inside components already connected via connect() from react-redux.

Say I got this kind of component hierarchy:

  • Provider

    • App

    • connect(mappedProps)(ConnectedComponent)



      • ConnectedComponent


      • connect(mappedProps)(ConnectedSubComponent)





        • ConnectedSubComponent






So it would crash at the deeper nested connect with this Invariant Violation error.

I should be able to plug into the store via a deep nested component/connect like that right?

@tuomohopia : if you can provide a small project that reproduces the issue separately, that would help.

But yes, in general, you should be able to nest connected components as much as you want.

@markerikson yeah I understand we need to produce a code base where this happens get to the bottom of this, I'm trying to put one together as my own is large and not open source.

@markerikson I've now managed to reproduce the error in a new project. In my case, it was produced by placing a connected component inside another library's component (react-native-popup-dialog).

Looks like at least in my code base it did not have anything to do with react-redux itself. It's good that you pushed me to replicate this in a new code base so we got to isolate the problem to another library!

In case anyone has the same problem I filed a bug report here:
https://github.com/jacklam718/react-native-popup-dialog/issues/168

This is the code base I used to replicate the issue with:
https://github.com/tuomohopia/reduce-fail

@tuomohopia : yep, exactly :) Every case of this we've seen so far has been some kind of a build configuration issue.

I'm having the same issue. In my case my server side Provider is part of another "shared" library in my private npm repo. When I pull from my repo, it works fine. When I npm link to this repo I get the error. But I don't have this issue prior to version 6 when I npm link.

Either wrap the root component in a <Provider>, or pass a custom 
React context provider to <Provider> and the corresponding
React context consumer to Connect(Connect(ProjectHOC)) in connect options.

@kmcrawford : correct - we only started using a singleton React.createContext() instance in v6.

@markerikson thanks, but that doesn't explain why the same code works as a private npm package and throws the error when running locally using npm link.

Below is how the code has looked for nearly a year, context in this case is just an empty object {} any thoughts to how I should be using React.createContext()?

<Provider store={store}>
    <StaticRouter location={req.url} context={context}>
          <div>{renderRoutes(Routes(contextPath))}</div>
    </StaticRouter>
</Provider>

The issue would likely be because different copies of React-Redux are ending up in your application. Since our internal ReactReduxContext instance is a singleton, if two different parts of the app are using different copies of React-Redux, they're not using the same ReactReduxContext instance, and so the connected components can't talk to <Provider>

@markerikson I think it's starting to make sense. So if my main app has react-redux in it's node_modules and when I npm link I'm using the react-redux in the linked package (which has the <Provider> in it) node_modules, could that cause this issue?

Yep, definitely would!

@markerikson Thanks! I will keep this thread posted if I get around this.

We hit the same error when upgrading from react-redux 5.1.1 to 6.0.1, and it was also due to a stray

import connect from "react-redux/lib/connect/connect"

statement.

(I import connect form react-redux)
With version 5.0.7 i could test my connected components like this:

// Libraries
import 'jest';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import { shallow, ReactWrapper } from 'enzyme';
import * as React from 'react';

// Reducers
import cartReducer from '../../../../Reducers/Cart/CartReducer';
import user from '../../../../Reducers/User/UserReducer';

// Modules
import Cart from '../../../../Modules/Cart/CartScene';

// setUp store
const myReducers = combineReducers({
  user: userReducer,
  cart: cartReducer
});

const store: any = createStore(
  myReducers,
  applyMiddleware(thunk)
);
let component: any;

const updateShallowComp = () => {
  component = shallow(
    <CartScene navigation={navigation} />,
    { context: { store } },
  );
  return component;
};

But with version 7.0.3 this throws me the same error of https://github.com/reduxjs/react-redux/issues/1117#issue-389662847

I do not user Provider because it's harder to access instance methods and states. How can I test my connected comps now without using a Provider

@nikoremi97 : we no longer use the old context API. Either pass the store directly as a prop to the connected component, or use a <Provider>.

@markerikson Thanks! I will keep this thread posted if I get around this.

@kmcrawford Did you manage to find a solution? I have the same problem on a project

Wanted to throw in my experience in case anybody else is seeing something similar.

I have a monorepo set up (using Yarn workspaces). I had already made sure that only one react-redux existed in my node_modules, but because I had set up Webpack with resolve.symlinks = false, I ended up having a Webpack build that copied in multiple react-reduxs, one for each of my "workspaces".

If you're seeing this issue with Webpack, open up a non-minified build and grep around for react-redux. You probably have multiple instances in there.

Hey @markerikson !
I'm publishing reusable modules with Redux logic attached to each of them, something similar to what @UserBug did.

Reading your comment, I understand that the Redux store have now becomes a singleton, so different package will result in different store.

In your opinion, what is the best practice to enable sharing the same store across these modules? Can we can an official documentation on this? I believe reusable modules are quite a common thing.

@jacklimwenjie : I'm not quite sure what you're saying there.

The described issue doesn't have anything to do with the Redux core or Redux stores. It's specifically about React-Redux using a React context instance. You need to make sure there is only a single copy of React and React-Redux loaded into your app, otherwise there may technically be multiple versions of the context that are created.

Note that this is not a problem that is specific to React-Redux, this would apply for _any_ library that creates a singleton React context instance for internal use.

I had the same problem as @Ashoat described. I fixed it with an alias in Webpack:

    resolve: {
      symlinks: false,
      alias: {
        react: path.resolve('./node_modules/react'),
        'react-redux': path.resolve('./node_modules/react-redux'),
      },
    },
Was this page helpful?
0 / 5 - 0 ratings

Related issues

teosz picture teosz  路  4Comments

nainardev picture nainardev  路  3Comments

a-koka picture a-koka  路  3Comments

fuchsberger picture fuchsberger  路  3Comments

esayemm picture esayemm  路  3Comments