React_on_rails: Can not register multiple components

Created on 30 Nov 2017  路  9Comments  路  Source: shakacode/react_on_rails

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?

Most helpful comment

There seem to be two separate issues here:

  1. Using ReactOnRails.register globally in a way that multiple invocations across bundles work together so that the last call doesn't clobber previous ones.
  2. Creating webpack chunks to avoid code duplication across multiple packs.

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.

All 9 comments

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 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.

There seem to be two separate issues here:

  1. Using ReactOnRails.register globally in a way that multiple invocations across bundles work together so that the last call doesn't clobber previous ones.
  2. Creating webpack chunks to avoid code duplication across multiple packs.

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

joeczucha picture joeczucha  路  6Comments

robwise picture robwise  路  3Comments

thomassnielsen picture thomassnielsen  路  4Comments

justin808 picture justin808  路  7Comments

amf9t2 picture amf9t2  路  8Comments