Invariant Violation: Could not find “store” in either the context or props of “Connect(SportsDatabase)”

后端 未结 9 1623
别那么骄傲
别那么骄傲 2020-12-12 10:36

Full code here: https://gist.github.com/js08/0ec3d70dfda76d7e9fb4

Hi,

  • I have an application where it shows different templates for desktop and mobile
相关标签:
9条回答
  • 2020-12-12 11:11

    in the end of your Index.js need to add this Code:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { BrowserRouter  } from 'react-router-dom';
    
    import './index.css';
    import App from './App';
    
    import { Provider } from 'react-redux';
    import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
    import thunk from 'redux-thunk';
    
    ///its your redux ex
    import productReducer from './redux/reducer/admin/product/produt.reducer.js'
    
    const rootReducer = combineReducers({
        adminProduct: productReducer
       
    })
    const composeEnhancers = window._REDUX_DEVTOOLS_EXTENSION_COMPOSE_ || compose;
    const store = createStore(rootReducer, composeEnhancers(applyMiddleware(thunk)));
    
    
    const app = (
        <Provider store={store}>
            <BrowserRouter   basename='/'>
                <App />
            </BrowserRouter >
        </Provider>
    );
    ReactDOM.render(app, document.getElementById('root'));

    0 讨论(0)
  • 2020-12-12 11:12

    It's pretty simple. You're trying to test the wrapper component generated by calling connect()(MyPlainComponent). That wrapper component expects to have access to a Redux store. Normally that store is available as context.store, because at the top of your component hierarchy you'd have a <Provider store={myStore} />. However, you're rendering your connected component by itself, with no store, so it's throwing an error.

    You've got a few options:

    • Create a store and render a <Provider> around your connected component
    • Create a store and directly pass it in as <MyConnectedComponent store={store} /> , as the connected component will also accept "store" as a prop
    • Don't bother testing the connected component. Export the "plain", unconnected version, and test that instead. If you test your plain component and your mapStateToProps function, you can safely assume the connected version will work correctly.

    You probably want to read through the "Testing" page in the Redux docs: https://redux.js.org/recipes/writing-tests.

    edit:

    After actually seeing that you posted source, and re-reading the error message, the real problem is not with the SportsTopPane component. The problem is that you're trying to "fully" render SportsTopPane, which also renders all of its children, rather than doing a "shallow" render like you were in the first case. The line searchComponent = <SportsDatabase sportsWholeFramework="desktop" />; is rendering a component that I assume is also connected, and therefore expects a store to be available in React's "context" feature.

    At this point, you have two new options:

    • Only do "shallow" rendering of SportsTopPane, so that you're not forcing it to fully render its children
    • If you do want to do "deep" rendering of SportsTopPane, you'll need to provide a Redux store in context. I highly suggest you take a look at the Enzyme testing library, which lets you do exactly that. See http://airbnb.io/enzyme/docs/api/ReactWrapper/setContext.html for an example.

    Overall, I would note that you might be trying to do too much in this one component and might want to consider breaking it into smaller pieces with less logic per component.

    0 讨论(0)
  • 2020-12-12 11:13

    As the official docs of redux suggest, better to export the unconnected component as well.

    In order to be able to test the App component itself without having to deal with the decorator, we recommend you to also export the undecorated component:

    import { connect } from 'react-redux'
    
    // Use named export for unconnected component (for tests)
    export class App extends Component { /* ... */ }
     
    // Use default export for the connected component (for app)
    export default connect(mapStateToProps)(App)
    

    Since the default export is still the decorated component, the import statement pictured above will work as before so you won't have to change your application code. However, you can now import the undecorated App components in your test file like this:

    // Note the curly braces: grab the named export instead of default export
    import { App } from './App'
    

    And if you need both:

    import ConnectedApp, { App } from './App'
    

    In the app itself, you would still import it normally:

    import App from './App'
    

    You would only use the named export for tests.

    0 讨论(0)
提交回复
热议问题