Reputation: 49
I'm currently using Rails with a ReactJS front end. I have most of my JS in an appropriate .js.jsx file, however, I have this sitting in index.html.erb under a script tag:
React.render(
React.createElement(CommentBox, {url: "/demo"}),
document.getElementById('content')
);
</script>
Under this configuration it works perfectly.
I appreciate the usual "Rails Way" is unobstrusive JS, but I'm having a hard time making that happen. If I simply move the above code into my main .js file, it loads before the content element exists and just renders nothing.
React-rails actually provides a special gem for unobtrusive JS, however I have two issues with that. Firstly, the documents don't refer to how to actually attach a URL tag, so neither of these work (no errors, just nothing renders):
<% react_component('CommentBox', url: '/demo') %>
<div data-react-class="CommentBox" data-react-props="url: /demo" />
The bigger issue however, is that the way the react-ujs gem works is by automatically embedding a few hundred lines of JavaScript before the body close tag. This doesn't feel less obtrusive than the four embedded lines I started with, or any improvement over it.
Am I missing something, in terms of why this method would be better, assuming I can get the first issue fixed?
Would there be a way to move this into the main .js file and still have it render? I could move it into a dedicated .js file and call it after the content tag, but that messes with the asset pipeline and replaces four lines of embedded scripting with a call to another whole file.
Half the rails community would call this embedded scripting heretical but it just keeps looking like the most efficient solution.
Upvotes: 0
Views: 1069
Reputation: 10039
Regarding your React-Rails component, it seems like you are simply missing the equals sign for the component to actually render.
Should be this:
<%= react_component('CommentBox', url: '/demo') %>
Instead, you have this:
<% react_component('CommentBox', url: '/demo') %>
Which doesn't actually render anything to the page with Rails.
Upvotes: 3
Reputation: 2674
If I simply move the above code into my main .js file, it loads before the content element exists and just renders nothing.
You can try doing something like:
document.addEventListener("DOMContentLoaded", function(event) {
React.render(React.createElement(CommentBox, { url: '/demo' }),
document.getElementById('content')
);
});
I think whether the unobtrusive method is 'better' or not is kind of a subjective question. I'm still in the 'figuring out' stages of using React.js with Rails right now too and I haven't settled on what to do. I kind of like the unobtrusive style, but react_ujs.js depends upon everything being in the global namespace and I'm also experimenting with switching my asset management over to webpack/npm, and everything there is nicely modulized there (which overall I like, but it sucks for react_ujs).
Upvotes: 1