

Server-rendered React components in Rails
source link: https://www.bensmithett.com/server-rendered-react-components-in-rails/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Server-rendered React components in Rails
Warning: experimental stuff ahead. Make sure you know more about running Rails in production than I do before you take this & run with it.
Source on GitHub
Here's my favourite slide from Pete Hunt's JSConf EU talk on React (which you should totally watch).

If you render a React component with the same data, it will always return the same result. It makes absolutely no difference whether you do that rendering on the client or the server.
That brings us to the official front end buzzword of 2014: Isomorphic JavaScript.
The Holy Grail. The united UI layer. Serve up real HTML on first page load, then kick off a client side JS app. All without duplicating a single line of UI code.
React makes this really easy if your back end is Node.js:
Awesome? Awesome. Except I spend most of my day working on a big old Rails app.
The react-rails gem
The official react-rails gem is pretty great. The current 1.0.0.pre release gives you
- React
- Asset pipeline JSX compilation
- An unobtrusive JS adapter that automatically mounts React components on HTML elements that have special data attributes (similar to jquery-ujs)
- A view helper
react_component
for generating that mount node
By default, the react_component
helper generates an empty div with data attributes, onto which react_ujs
comes along and mounts a component.
However, thanks to John Lynch, if you specify the :prerender => true
option the helper actually executes (via ExecJS) React.renderComponentToString
and renders the component server side.
The Rails code
I built a tiny, super simple, stock Rails app using the CommentBox
component from the React tutorial to try this out. It looks like this:

The whole thing is a React component composed of smaller React components, all server-rendered using the exact same JS files that are used by the client side JS app.
Here's index.html.erb
in its entirety:
The Rails controller defines a presenter that gives the component all the initial data it needs to render.
When the page loads, react_ujs sees the component & calls React.renderComponent
on it, which is smart enough to preserve the server rendered markup & just add event handlers.
With the client side app bootstrapped, the form submits via ajax & adds the new comment to the list. But if the JS fails to load or initialise, the form will submit normally with a full page refresh. Progressive enhancement ahoy!
You need to make the Rails controller handle both the ajax & non-ajax scenarios.
Back in the client side CommentBox component, when the ajax request completes, we simply update it with the new state & React does its thing.
This is so awesome!
You don't need a DOM on the server and, React being React, you're not even really thinking about the DOM on the client. Because components are basically just idempotent functions, you can render them in any environment you like as long as you have some data representing the current state and the ability to execute JS.
There are some rough edges. Forms are harder. There are no Rails view helpers in React land. Passing in CSRF tokens & hand coding a hidden field every time is gonna get old fast.
That said, after playing around with this for a day, using different templates & languages depending on whether you're rendering on the client or server feels totally arbitrary & stupid. The sometimes ERB, sometimes Handlebars workflow feels so kludgy now.
I'm looking forward to this future :D
Side note: If you don't want to execute JS right there in your Rails app, another interesting approach is to spin up a Node.js app whose sole responsibility is rendering React components to strings. There's an example of this views-as-a-service-over-http setup in the React repo.
Recommend
-
164
Next.js Getting Started Visit https://nextjs.org/learn to get started with Next.js. Documentation Visit
-
132
Attaching React.js to a template rendered on the server with Twig React.js is a JavaScript view library that allows developers to create interfaces is a structured way based on a hierarch...
-
93
The Performance Cost of Server Side Rendered React on Node.jsThe Performance Cost of Server Side Rendered React on Node.jsI like
-
9
🌶 Spice up your server-side rendered apps with Stimulus and Turbolinks
-
8
Testing React.js components with Jest in Rails+Webpacker+Webpack environment Around a month ago, I worked on a task, which required a more dynamic frontend behavior. I worked on a component with 2 selects and 2 date pickers and d...
-
8
Remix JS: Let’s Create a Server-Side Rendered AppAn introduction to Remix JS and Remix features. How to build an app with Remix. How to use in-built route loading and nested routes
-
9
Building server-rendered search for static sites with 11ty Serverless, Netlify, and AlgoliaProgressive enhancement is an important topic when creating any web site or app. What h...
-
5
React报错之Rendered more hooks than during the previous render ...
-
5
Are you looking for a simple and efficient way to render Markdown content in your React project? Look no further than Markdown Parser React! Markdown Parser React is a lightweight, flexible, and easy-to-...
-
5
How To Build Server-Side Rendered (SSR) Svelte Apps With SvelteKitSvelteKit is a framework for building apps using Svelte. You can use SvelteKit to build a variety of apps that can...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK