[![Gem](https://img.shields.io/gem/v/react-rails.svg?style=flat-square)](http://rubygems.org/gems/react-rails) [![Build Status](https://img.shields.io/travis/reactjs/react-rails/master.svg?style=flat-square)](https://travis-ci.org/reactjs/react-rails) [![Gemnasium](https://img.shields.io/gemnasium/reactjs/react-rails.svg?style=flat-square)](https://gemnasium.com/reactjs/react-rails) [![Code Climate](https://img.shields.io/codeclimate/github/reactjs/react-rails.svg?style=flat-square)](https://codeclimate.com/github/reactjs/react-rails) [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/reactjs/react-rails.svg?style=flat-square)](https://codeclimate.com/github/reactjs/react-rails/coverage) * * * # react-rails `react-rails` makes it easy to use [React](http://facebook.github.io/react/) and [JSX](http://facebook.github.io/react/docs/jsx-in-depth.html) in your Ruby on Rails (3.2+) application. `react-rails` can: - Provide [various `react` builds](#reactjs-builds) to your asset bundle - Transform [`.jsx` in the asset pipeline](#jsx) - [Render components into views and mount them](#rendering--mounting) via view helper & `react_ujs` - [Render components server-side](#server-rendering) with `prerender: true` - [Generate components](#component-generator) with a Rails generator ## Installation Add `react-rails` to your gemfile: ```ruby gem 'react-rails', '~> 1.0' ``` Next, run the installation script: ```bash rails g react:install ``` This will: - create a `components.js` manifest file and a `app/assets/javascripts/components/` directory, where you will put your components - place the following in your `application.js`: ```js //= require react //= require react_ujs //= require components ``` ## Usage ### React.js builds You can pick which React.js build (development, production, with or without [add-ons]((http://facebook.github.io/react/docs/addons.html))) to serve in each environment by adding a config. Here are the defaults: ```ruby # config/environments/development.rb MyApp::Application.configure do config.react.variant = :development end # config/environments/production.rb MyApp::Application.configure do config.react.variant = :production end ``` To include add-ons, use this config: ```ruby MyApp::Application.configure do config.react.addons = true # defaults to false end ``` After restarting your Rails server, `//= require react` will provide the build of React.js which was specified by the configurations. `react-rails` offers a few other options for versions & builds of React.js. See [VERSIONS.md](https://github.com/reactjs/react-rails/blob/master/VERSIONS.md) for more info about using the `react-source` gem or dropping in your own copies of React.js. ### JSX After installing `react-rails`, restart your server. Now, `.js.jsx` files will be transformed in the asset pipeline. `react-rails` currently ships with two transformers, to convert jsx code - * `BabelTransformer` using [Babel](http://babeljs.io), which is the default transformer. * `JSXTransformer` using `JSXTransformer.js` #### BabelTransformer options You can use babel's [transformers](http://babeljs.io/docs/advanced/transformers/) and [custom plugins](http://babeljs.io/docs/advanced/plugins/), and pass [options](http://babeljs.io/docs/usage/options/) to the babel transpiler adding following configurations: ```ruby config.react.jsx_transform_options = { blacklist: ['spec.functionName', 'validation.react'], # default options optional: ["transformerName"], # pass extra babel options whitelist: ["useStrict"] # even more options } ``` Under the hood, `react-rails` uses [ruby-babel-transpiler](https://github.com/babel/ruby-babel-transpiler), for transformation. #### JSXTransformer options To use old JSXTransformer you can use `React::JSX.transformer_class = React::JSX::JSXTransformer` You can use JSX `--harmony` or `--strip-types` options by adding a configuration: ```ruby config.react.jsx_transform_options = { harmony: true, strip_types: true, # for removing Flow type annotations asset_path: "path/to/JSXTransformer.js", # if your JSXTransformer is somewhere else } ``` ### Rendering & mounting `react-rails` includes a view helper (`react_component`) and an unobtrusive JavaScript driver (`react_ujs`) which work together to put React components on the page. You should require the UJS driver in your manifest after `react` (and after `turbolinks` if you use [Turbolinks](https://github.com/rails/turbolinks)). The __view helper__ puts a `div` on the page with the requested component class & props. For example: ```erb <%= react_component('HelloMessage', name: 'John') %>
``` On page load, the __`react_ujs` driver__ will scan the page and mount components using `data-react-class` and `data-react-props`. Before page unload, it will unmount components (if you want to disable this behavior, remove `data-react-class` attribute in `componentDidMount`). `react_ujs` uses Turbolinks events if they're available, otherwise, it uses native events. __Turbolinks >= 2.4.0__ is recommended because it exposes better events. The view helper's signature is: ```ruby react_component(component_class_name, props={}, html_options={}) ``` - `component_class_name` is a string which names a globally-accessible component class. It may have dots (eg, `"MyApp.Header.MenuItem"`). - `props` is either an object that responds to `#to_json` or an already-stringified JSON object (eg, made with Jbuilder, see note below). - `html_options` may include: - `tag:` to use an element other than a `div` to embed `data-react-class` and `-props`. - `prerender: true` to render the component on the server. - `**other` Any other arguments (eg `class:`, `id:`) are passed through to [`content_tag`](http://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-content_tag). ### Server rendering (This documentation is for the __`master` branch__, please check the [__`1.0.0` README__](https://github.com/reactjs/react-rails/tree/v1.0.0#server-rendering) for that API!) To render components on the server, pass `prerender: true` to `react_component`: ```erb <%= react_component('HelloMessage', {name: 'John'}, {prerender: true}) %>