renchap/webpacker-react

Redux integration with React

zenobht opened this issue · 3 comments

I have been using webpacker-react to render simple components in a ruby rails application. But I have a need now to share state with the components, and these components are at different places in ruby applications. I want to integrate redux with my application.

  1. Can I use redux with WebpackerReact-react?
  2. If yes, any example code of how to set it up with WebpackerReact.setup()?

I have tried the following without success

const store = createStore(combineReducers({ [STATE_KEY]: info }));
const TestComp = (
  <Provider store={store}>
      <PP />
    </Provider>
);

WebpackerReact.setup({
  TestComp
});

@jbharat
Yes you can use redux, webpacker-react is a thin wrapper over webpacker/webpack so if you can webpack it, you are likely able to use it here too.
Example from react-rails:
reactjs/react-rails#878 (comment)
Most solutions are portable between these projects.

@BookOfGreg Thank you. I played around a bit with different code. Here is what I tried

const store = createStore(combineReducers({ [STATE_KEY]: info }));

const composeWithRedux = Component => (
  <Provider store={store}>
    <Component />
  </Provider>
);

WebpackerReact.setup({
  ComponentA,
  CompB: composeWithRedux(B),
  CompC: composeWithRedux(C),
});

this throws the following error VM720 .... Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. This happens at ReactDOM.render in the source code.

Then I started digging with the source code and in webpacker-react/javascript/webpacker_react-npm-module/src/index.js I changed

let reactElement = React.createElement(component, props)
    if (this.wrapForHMR) {
      reactElement = this.wrapForHMR(reactElement)
    }
    ReactDOM.render(reactElement, node)

to

let reactElement = component
    if (this.wrapForHMR) {
      reactElement = this.wrapForHMR(reactElement)
    }
    ReactDOM.render(reactElement, node)

This got everything up and running with redux state. CompB and CompC both share same state.
I am not sure if it is a bug, but if we avoid calling createElement directly, and let react handle it, it would solve this issue.

Got it running. Every component that needs redux should implement as below

const Comp = connect(mapStateToProps, mapDispatchToProps)(ComponentA);

export default props => composeWithRedux(Comp, props);
export function composeWithRedux(Component, props) {
  return (
    <Provider store={store}>
      <Component {...props} />
    </Provider>
  );
}

Closing this bug