I have two components (Component1 and Component2). Sometimes I need both of them on the same page, sometimes just one.
I don't want load scripts that I do not need on the page. So, I separated load files like this:
javascript/packs/component1_bundle.jsx
import ReactOnRails from 'react-on-rails';
import Component1 from '../bundles/components/Component1';
ReactOnRails.register({ Component1 });
javascript/packs/component2_bundle.jsx
import ReactOnRails from 'react-on-rails';
import Component2 from '../bundles/components/Component2';
ReactOnRails.register({ Component2 });
Then, when I need both components on the page, I do this:
= javascript_pack_tag 'component1_bundle'
= javascript_pack_tag 'component2_bundle'
= react_component("Component1")
= react_component("Component2")
The second register overrides the first one, and I have this error:
Uncaught Error: ReactOnRails encountered an error while rendering component: Component1.
Original message: Could not find component registered with name Component1.
Registered component names include [ Component2 ]. Maybe you forgot to register the component?
There is no error and everything works fine when I register components in the same file:
javascript/packs/component1_and_component2_bundle.jsx
import ReactOnRails from 'react-on-rails';
import Component1 from '../bundles/components/Component1';
import Component1 from '../bundles/components/Component2';
ReactOnRails.register({ Component1 });
ReactOnRails.register({ Component2 });
How to register components separately, only ones that I really need?
I experienced a very similar issue and was surprised it didn't work out of the box. I suspect it may be a design choice due to the way packs/bundles are handled however the documentation should explain this. New to using the gem so will wait for maintainers to explain.
@chumakoff Did you try to extract vendor bundle into separate chunk?
You can check Webpack configs from tutorial rails app to understand how to do it.
@railsme No, I didn't. And I can't understand how to do that.
@chumakoff Prevent code duplications in webpack
@chumakoff You can create separate bundles. I don't think the rails/webpacker way supports this, but I could be mistaken.
@railsme is correct on this issue.
@chumakoff
https://github.com/rails/webpacker/blob/master/docs/webpack.md#add-common-chunks
There seem to be two separate issues here:
ReactOnRails.register globally in a way that multiple invocations across bundles work together so that the last call doesn't clobber previous ones.Some comments here are addressing (2), which is indeed related, but (1) seems to be the proximate issue from the original poster.
This issue appears to be that, by doing import ReactOnRails twice, you are creating two separate internal component stores. I was able to get around this by doing the following, which is not ideal, but keep in mind ReactOnRails exports itself to window. anyways:
window.ReactOnRails = window.ReactOnRails || require('react-on-rails').default;
import Component1 from '../bundles/components/Component1';
ReactOnRails.register({ Component1 });
window.ReactOnRails = window.ReactOnRails || require('react-on-rails').default;
import Component1 from '../bundles/components/Component2';
ReactOnRails.register({ Component2 });
And then this works:
= javascript_pack_tag 'component1_bundle'
= javascript_pack_tag 'component2_bundle'
= react_component("Component1")
= react_component("Component2")
Hope this helps others who are running into the same problem, and just need to get this working without restructuring their webpacker configuration or pack setup.
@rubiety are you using Webpack v4? I'm thinking that this maybe should be handled at lower level. Nevertheless, thank you for posting this! If you like, consider adding a file to the docs directory in a PR.
Is this still the way to make this work? I'm running into the same issue.
Most helpful comment
There seem to be two separate issues here:
ReactOnRails.registerglobally in a way that multiple invocations across bundles work together so that the last call doesn't clobber previous ones.Some comments here are addressing (2), which is indeed related, but (1) seems to be the proximate issue from the original poster.
This issue appears to be that, by doing
import ReactOnRailstwice, you are creating two separate internal component stores. I was able to get around this by doing the following, which is not ideal, but keep in mindReactOnRailsexports itself towindow.anyways:And then this works:
Hope this helps others who are running into the same problem, and just need to get this working without restructuring their webpacker configuration or pack setup.