A lo-fi way to render client- and server-side React components from Ruby:
class ExampleComponent extends React.Component {
render() {
return <marquee>Hello Ruby { this.props.example }</marquee>
}
}
RenderReact.on_client_and_server("ExampleComponent", { example: "!" })
# =>
<div id="RenderReact-caac405e-1714-495e-aeb4-77b42be42291">
<marquee data-reactroot="" data-reactid="1" data-react-checksum="441921122">
<!-- react-text: 2 -->Hello Ruby <!-- /react-text --><!-- react-text: 3 -->!<!-- /react-text -->
</marquee>
</div>
<script>
RenderReact.ReactDOM.render(
RenderReact.React.createElement(
RenderReact.components.ExampleComponent, {"example":"!"}
),
document.getElementById('RenderReact-caac405e-1714-495e-aeb4-77b42be42291')
)
</script>
It is bring your own tooling: React is not included, nor any ES6 transpilers or module bundlers. It expects you to prepare the JavaScript bundle file in a specific format, which must contain React and all of your components.
If you are looking for higher-level alternatives, checkout react_on_rails or react-rails.
Add to your Gemfile
:
gem 'render_react'
RenderReact expects the JavaScript bundle to include a global variable called RenderReact
with the following contents:
{
React: [variable which contains React],
ReactDOM: [variable which contains ReactDOM],
ReactDOMServer: [variable which contains ReactDOMServer],
components: {
ComponentIdentifier1: [variable which contains the component 1],
ComponentIdentifier2: [variable which contains the component 2],
...
}
}
- Where is React? See first paragraph of https://facebook.github.io/react/docs/react-api.html
- Where is ReactDOM? See first paragraph of https://facebook.github.io/react/docs/react-dom.html
- Where is ReactDOMServer? See first paragraph of https://facebook.github.io/react/docs/react-dom-server.html
You can have two different javascript bundle files - one for server rendering, and one for client-rendering.
- The client bundle has to be included into your application by a method of your choice. You may skip passing in
ReactDOMServer
for the client bundle - The server bundle has to be passed to
RenderReact
(see Usage section). You may skip passing inReactDOM
for the server bundle
import React from 'react'
import ReactDOM from 'react-dom'
import ReactDOMServer from 'react-dom/server'
import ExampleComponent from './components/example_component'
export default {
React: React,
ReactDOM: ReactDOM,
ReactDOMServer: ReactDOMServer,
components: {
ExampleComponent: ExampleComponent
}
}
Gets imported as RenderReact
window.RenderReact = {
React: React,
ReactDOM: ReactDOM,
ReactDOMServer: ReactDOMServer,
components: {
ExampleComponent: ExampleComponent
}
}
Create a RenderReact context by passing your server-side JavaScript bundle:
RenderReact.create_context! File.read('path/to/your/server-bundle.js'), mode: :client_and_server
You can use it without a server-side bundle by not passing any file source.
The optional mode:
keyword argument can have one of the following values
:client_and_server
(default) - component will be rendered server-side and mounted in the client:client
- component will be mounted in the client:server
- component will be render statically
You can then render a component with
RenderReact.("ExampleComponent", { example: "prop" })
It is possible to overwrite the context-rendering-mode by using specfic render methods:
RenderReact.on_client_and_server("ExampleComponent") # server- and client-side
RenderReact.on_client("ExampleComponent") # only client-side
RenderReact.on_server("ExampleComponent") # only static
Copyright (C) 2017 Jan Lelis https://janlelis.com. Released under the MIT license.
React is BSD licensed.