Search code examples
reduxreact-reduxdialogmaterial-uistore

Could not find "store" error in connected component nested in Dialog


I have a connected component that will render fine when wrapped with a <div>, but when I wrap with Dialog component, I keep getting the dreaded: Could not find "store" in the context of "Connect(MyComponent)". Yes, the root <App /> is wrapped with <Provider /> and the store is fine, all other pages, components, connected items have access to store, just not when rendered in this Dialog.

This has not been a problem in the past, and was obviously hosed as a side effect from some dependency maintenance that was occurring. If I swap the Dialog component's underlying lib from MUI 0.20 to version 3 (via @material-ui/core/Dialog) it works fine. There's something going on with a balance between mui 0.20 and updated react-ish dependencies.

Just wondering if anyone has experienced this?

// Where it's invoked...

<ParentPageComp>
  <Dialog open>
    <MyConnectedComponent />
  </Dialog>
</ParentPageComp>

// What is being attempted to render...

class MyConnectedComponent extends React.Component {
  render() {
    return <div>Yeppers</div>;
  }
 }

export default connect(state => ({ blah: state.blah }))(MyConnectedComponent);

Again, if I replace <Dialog> with <div>, all is normal.

Not sure if this is relevant, but the parent components wrapping the Dialog are async loaded with hooks... even when replacing with code splitting mechanism of react-loadable, I get the same naughty results.

Using:

  • Material-ui 0.20.2 (yes, the old one)
  • React 16.8.6
  • Redux 4.0.1
  • React-redux 7.1.0
  • React-router-dom 5.0.0

Solution

  • Old version can easily block context propagation thru DOM hierarchy. You can manually carry context over <Dialog/> component like this

    import { Provider, ReactReduxContext } from 'react-redux';
    
    //...
    render() {
        return (
            <ParentPageComp>
                <ReactReduxContext.Consumer>
                    {((ctx) => (
                        <Dialog open>
                            <Provider store={ctx.store}>  /* make store available again */
                                <MyConnectedComponent />
                            </Provider>
                        </Dialog>
                    )).bind(this) // Dont forget to bind this
                    }
                </ReactReduxContext.Consumer>
            </ParentPageComp>
        );
    }