Renders React as HTML
The docs can be found at https://hexdocs.pm/react_render.
def deps do
[
{:react_render, "~> 3.0.0"}
]
end
-
Add
react_render
to your dependencies in package.json"react_render": "file:../deps/react_render"
-
Run
npm install
npm install
-
Create a file named
render_server.js
in yourassets
folder and add the followingrequire('@babel/polyfill') require('@babel/register')({cwd: __dirname}) module.exports = require('react_render/priv/server')
Note: You must move any
@babel
used for server-side rendering fromdevDependencies
todependencies
in yourpackage.json
file. This is required when installing dependencies required for production as these packages. -
Add
ReactRender
to your Supervisor as a child. We're using the absolute path to ensure we are specifying the correct working directory that contains therender_server.js
file we created earlier.render_service_path = "#{File.cwd!}/assets" pool_size = 4 supervisor(ReactRender, [[render_service_path: render_service_path, pool_size: 4]])
-
Create a react component like:
import React, {Component, createElement} from 'react' class HelloWorld extends Component { render() { const {name} = this.props return <div>Hello {name}</div> } } export default HelloWorld
-
Call
ReactRender.render/2
inside the action of your controllerdef index(conn, _params) do component_path = "#{File.cwd!}/assets/js/HelloWorld.js" props = %{name: "Revelry"} { :safe, helloWorld } = ReactRender.render(component_path, props) render(conn, "index.html", helloWorldComponent: helloWorld) end
component_path
can either be an absolute path or one relative to the render service. The stipulation is that components must be in the same path or a sub directory of the render service. This is so that the babel compiler will be able to compile it. The service will make sure that any changes you make are picked up. It does this by removing the component_path from node'srequire
cache. If do not want this to happen, make sure to addNODE_ENV
to your environment variables with the valueproduction
. -
Render the component in the template
<%= raw @helloWorldComponent %>
-
To hydrate server-created components in the client, add the following to your
app.js
import {hydrateClient} from 'react_render/priv/client' import HelloWorld from './HelloWorld.js' function getComponentFromStringName(stringName) { // Map string component names to your react components here if (stringName === 'HelloWorld') { return HelloWorld } return null } hydrateClient(getComponentFromStringName)
-
Update
assets/webpack.config
to include under theresolve
section so that module resolution is handled properly:resolve: { symlinks: false }