GoogleChromeLabs / progressive-rendering-frameworks-samples

Samples and demos from the Progressive Rendering I/O talk
Apache License 2.0
411 stars 42 forks source link

Redux can´t find store in Hydrator child #2

Open secretlifeof opened 5 years ago

secretlifeof commented 5 years ago

Thank you very much for providing your samples!

When trying to integrate redux into "react-progressive-hydration" it returns: Invariant Violation: Could not find "store" in the context of "Connect(ReduxTest)". Either wrap the root component in a , or pass a custom React context provider to and the corresponding React context consumer to Connect(ReduxTest) in connect options.

The Provider is provided in client.js.

This is the component wrapped in your hydrator component

import React, { useCallback } from 'react'
// import { useDispatch, useMappedState } from 'redux-react-hook'
import { connect } from 'react-redux'

const ReduxTest = props => {
    // const mapState = useCallback(state => {
    //  const visibility =
    //      state.booleansToggle && state.booleansToggle.toggleList ? state.booleansToggle.toggleList.projectDetail : false

    //  return visibility
    // }, [])
    // const projectDetailVisibility = useMappedState(mapState)

    return <div>TEST</div>
}

const mapStateToProps = (state, ownProps) => {
    return {
        visibility : state.booleansToggle.toggleList.projectDetail
    }
}

export default connect(mapStateToProps)(ReduxTest)

Can you please explain the cause of this error? Do you have a workaround for this? Thank you very much in advance.

developit commented 5 years ago

Hi there!

Thanks for opening an issue. This is caused by the Hydrate component failing to pass React Context down through the tree, which was something we skirted around to keep things simple for demonstration purposes. It is possible to stitch context across trees, however - hopefully we can get this repo updated with a version of Hydrate that does just that.

Here's a workaround in the meantime:

function GetContext(props, context) {
  return props.children(context);
}
GetContext.contextTypes = {
  store: Boolean  // fake contexttype
};

<GetContext>{context =>
  <Hydrator context={context} load={() => import('./other')} />
}</GetContext>

other.js:

const withPropsContext = Child => class ApplyContext extends Component {
  getChildContext() {
    return this.props.context;
  }
  render() {
    const { context, ...props } = this.props;
    return <Child {...props} />;
  }
}

const ReduxTest = () => <div>TEST</div>

// you only have to do this for the outermost hydrator child:
export default withPropsContext(connect(mapStateToProps)(ReduxTest))