You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> ***Additionally: `0.x` branch directly follows React versions, `1.x` will not do so.***
15
15
16
-
react-rails is a ruby gem which makes it easier 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 application.
16
+
`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.1+) application.`react-rails` can:
17
17
18
-
19
-
1. Making it easy to include `react.js` as part of your dependencies in `application.js`.
20
-
2. Transforming JSX into regular JS on request, or as part of asset precompilation.
21
-
3. View helpers to render React components in an unobtrusive style and/or on the server.
18
+
- Provide [various `react` builds](#reactjs-builds) to your asset bundle
19
+
- Transform [`.jsx` in the asset pipeline](#jsx)
20
+
-[Render components into views and mount them](#rendering--mounting) via view helper & `react_ujs`
21
+
-[Render components server-side](#server-rendering) with `prerender: true`.
22
+
-[Generate components](#component-generator) with a Rails generator
22
23
23
24
## Installation
24
25
25
-
We're specifically targeting versions of Ruby on Rails which make use of the asset pipeline, which means Rails 3.1+.
26
-
27
-
As with all gem dependencies, we strongly recommend adding `react-rails` to your `Gemfile` and using `bundler` to manage your application's dependencies.
26
+
Add `react-rails` to your gemfile:
28
27
29
28
```ruby
30
29
# Gemfile
@@ -40,43 +39,51 @@ Next, run the installation script.
40
39
rails g react:install
41
40
```
42
41
43
-
This will require `react.js`, `react_ujs.js`, and a `components.js` manifest file in application.js, and create a directory named `app/assets/javascripts/components` for you to store React components in.
42
+
This will:
43
+
- create a `components.js` manifest file and a `app/assets/javascripts/components/` directory, where you will put your components
44
+
- place the following in your `application.js`:
44
45
45
-
## Usage
46
+
```js
47
+
//= require react
48
+
//= require react_ujs
49
+
//= require components
50
+
```
46
51
47
-
### react.js
52
+
##Usage
48
53
49
-
In order to use React client-side in your application, you must make sure the browser requests it. One way to do that is to drop `react.js` into `vendor/assets/javascript/` and by default your application manifest will pick it up. There are downsides to this approach, so we made it even easier. Once you have `react-rails` installed, you can just add a line into your config file (see Configuring) and require react directly in your manifest:
54
+
### React.js builds
50
55
51
-
You can `require` it in your manifest:
56
+
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:
52
57
53
-
```js
54
-
// app/assets/javascripts/application.js
58
+
```ruby
59
+
# config/environments/development.rb
60
+
MyApp::Application.configure do
61
+
config.react.variant =:development
62
+
end
55
63
56
-
//= require react
64
+
# config/environments/production.rb
65
+
MyApp::Application.configure do
66
+
config.react.variant =:production
67
+
end
57
68
```
58
69
59
-
Alternatively, you can include it directly as a separate script tag:
60
-
61
-
```erb
62
-
# app/views/layouts/application.html.erb
70
+
To include add-ons, use this config:
63
71
64
-
<%= javascript_include_tag "react" %>
72
+
```ruby
73
+
MyApp::Application.configure do
74
+
config.react.addons =true# defaults to false
75
+
end
65
76
```
66
77
67
-
### JSX
78
+
After restarting your Rails server, `//= require react` will provide the build of React.js which was specified by the configurations.
68
79
69
-
To transform your JSX into JS, simply create `.js.jsx`files. These files will be transformed on request, or precompiled as part of the `assets:precompile` task.
80
+
In a pinch, you can also provide your own copies of React.js and JSXTransformer. Just add `react.js` or `JSXTransformer.js` (case-sensitive) files to `app/vendor/assets/javascripts/react/` and restart your development server. If you need different versions of React in different environments, put them in directories that match `config.react.variant`. For example, if you set `config.react.variant = :development`, you could put a copy of `react.js` in `/vendor/assets/react/development/`.
70
81
71
-
CoffeeScript files can also be used, by creating `.js.jsx.coffee` files. We also need to embed JSX inside backticks so CoffeeScript ignores the syntax it doesn't understand. Here's an example:
82
+
### JSX
72
83
73
-
```coffee
74
-
Component=React.createClass
75
-
render:->
76
-
`<ExampleComponent videos={this.props.videos} />`
77
-
```
84
+
After installing `react-rails`, restart your server. Now, `.js.jsx` files will be transformed in the asset pipeline.
78
85
79
-
You can use the`--harmony` or `--strip-types` options by adding a configuration to `application.rb`:
86
+
You can use JSX`--harmony` or `--strip-types` options by adding a configuration:
80
87
81
88
```ruby
82
89
config.react.jsx_transform_options = {
@@ -85,145 +92,95 @@ You can use the `--harmony` or `--strip-types` options by adding a configuration
85
92
}
86
93
```
87
94
88
-
### Unobtrusive JavaScript
89
-
90
-
`react_ujs` will call `React.render` for every element with `data-react-class` attribute. React properties can be specified by `data-react-props` attribute in JSON format. For example:
95
+
To use CoffeeScript, create `.js.jsx.coffee` files and embed JSX inside backticks, for example:
91
96
92
-
```erb
93
-
<!-- react_ujs will execute `React.render(HelloMessage({name:"Bob"}), element)` -->
`react_ujs` will also scan DOM elements and call `React.unmountComponentAtNode` on page unload. If you want to disable this behavior, remove `data-react-class` attribute in `componentDidMount`.
98
-
99
-
To use `react_ujs`, simply `require` it after `react` (and after `turbolinks` if [Turbolinks](https://github.com/rails/turbolinks) is used).
103
+
### Rendering & mounting
100
104
101
-
**Note:**_Turbolinks >= 2.4.0 is recommended. For older versions `react_ujs` will disable the Turbolinks cache to ensure components are correctly unmounted. See [#87](https://github.com/reactjs/react-rails/issues/87) for details._
105
+
`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))
102
106
103
-
```js
104
-
// app/assets/javascripts/application.js
107
+
The __view helper__ puts a `div` on the page with the requested component class & props. For example:
There is a view helper method `react_component`. It is designed to work with `react_ujs` and takes a React class name, properties, and HTML options as arguments:
115
+
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.
119
118
120
-
By default, a `<div>` element is used. Other tag and HTML attributes can be specified:
You can pass prepared JSON directly to the helper, as well.
125
+
-`component_class_name` is a string which names a globally-accessible component class. It may have dots (eg, `"MyApp.Header.MenuItem"`).
126
+
-`props` is either an object that responds to `#to_json` or an already-stringified JSON object (eg, made with Jbuilder, see note below)
127
+
-`html_options` may include:
128
+
-`tag:` to use an element other than a `div` to embed `data-react-class` and `-props`.
129
+
-`prerender: true` to render the component on the server.
130
+
-`**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).
-`react-rails` must load your code. By convention, it uses `components.js`, which was created by the install task. This file must include your components _and_ their dependencies (eg, Underscore.js).
150
+
- Your components must be accessible in the global scope. If you are using `.js.jsx.coffee` files then the wrapper function needs to be taken into account:
- Your code can't reference `document`. Prerender processes don't have access to `document`, so jQuery and some other libs won't work in this environment :(
167
159
168
-
However ReactJS expects the collection of props provided to a component to be a key-value object. Therefore, if you want to use your Jbuilder templates directly with the helper, you will need to wrap your index.json.jbuilder array with a root node like so:
160
+
You can configure your pool of JS virtual machines and specify where it should load code:
React components can also use the same ExecJS mechanisms in Sprockets to execute JavaScript code on the server, and render React components to HTML to be delivered to the browser, and then the `react_ujs` script will cause the component to be mounted. In this way, users get fast initial page loads and search-engine-friendly pages.
186
-
187
-
#### ExecJS
188
-
189
-
By default, ExecJS will use node.js in an external process to run JS code. Because we will be executing JS on the server in production, an in-process, high-performance JS VM should be used. Simply add the proper one for your platform to your Gemfile:
190
-
191
-
```ruby
192
-
gem "therubyracer", :platforms => :ruby
193
-
gem "therubyrhino", :platforms => :jruby
194
-
```
195
-
196
-
#### components.js
197
-
198
-
In order for us to render your React components, we need to be able to find them and load them into the JS VM. By convention, we look for a `assets/javascripts/components.js` file through the asset pipeline, and load that. For example:
199
-
200
-
```sass
201
-
// app/assets/javascripts/components.js
202
-
//= require_tree ./components
203
-
```
204
-
205
-
This will bring in all files located in the `app/assets/javascripts/components` directory. You can organize your code however you like, as long as a request for `/assets/javascripts/components.js` brings in a concatenated file containing all of your React components, and each one has to be available in the global scope (either `window` or `global` can be used). For `.js.jsx` files this is not a problem, but if you are using `.js.jsx.coffee` files then the wrapper function needs to be taken into account:
206
-
207
-
```coffee
208
-
Component=React.createClass
209
-
render:->
210
-
`<ExampleComponent videos={this.props.videos} />`
211
-
212
-
window.Component= Component
213
-
```
214
-
215
-
#### View Helper
216
-
217
-
To take advantage of server rendering, use the same view helper `react_component`, and pass in `prerender: true` in the `options` hash.
This will return the fully rendered component markup, and as long as you have included the `react_ujs` script in your page, then the component will also be instantiated and mounted on the client.
223
-
224
-
### Component Generator
225
-
226
-
react-rails ships with a Rails generator to help you get started with a simple component scaffold. You can run it using `rails generate react:component ComponentName`. The generator takes an optional list of arguments for default propTypes, which follow the conventions set in the [Reusable Components](http://facebook.github.io/react/docs/reusable-components.html) section of the React documentation.
183
+
react-rails ships with a Rails generator to help you get started with a simple component scaffold. You can run it using `rails generate react:component ComponentName`. The generator takes an optional list of arguments for default propTypes, which follow the conventions set in the [Reusable Components](http://facebook.github.io/react/docs/reusable-components.html) section of the React documentation.
227
184
228
185
For example:
229
186
@@ -276,55 +233,24 @@ The following additional arguments have special behavior:
276
233
277
234
Note that the arguments for `oneOf` and `oneOfType` must be enclosed in single quotes to prevent your terminal from expanding them into an argument list.
278
235
279
-
## Configuring
280
-
281
-
### Variants
282
-
283
-
There are 2 variants available. `:development` gives you the unminified version of React. This provides extra debugging and error prevention. `:production` gives you the minified version of React which strips out comments and helpful warnings, and minifies.
284
-
285
-
```ruby
286
-
# config/environments/development.rb
287
-
MyApp::Application.configure do
288
-
config.react.variant =:development
289
-
end
290
-
291
-
# config/environments/production.rb
292
-
MyApp::Application.configure do
293
-
config.react.variant =:production
294
-
end
295
-
```
296
-
297
-
### Add-ons
236
+
### Jbuilder & react-rails
298
237
299
-
Beginning with React v0.5, there is another type of build. This build ships with some "add-ons" that might be useful - [take a look at the React documentation for details](http://facebook.github.io/react/docs/addons.html). In order to make these available, we've added another configuration (which defaults to `false`).
238
+
If you use Jbuilder to pass JSON string to `react_component`, make sure your JSON is a stringified hash, not an array. This is not the Rails default -- you should add the root node yourself. For example:
For performance and thread-safety reasons, a pool of JS VMs are spun up on application start, and the size of the pool and the timeout on requesting a VM from the pool are configurable.
310
-
311
-
```ruby
312
-
# config/environments/application.rb
313
-
# These are the defaults if you dont specify any yourself
*`react_js`: where you want to grab the javascript library from
325
-
*`component_filenames`: an array of filenames that will be requested from the asset pipeline and concatenated together
326
-
*`replay_console`: additional debugging by replaying any captured console messages from server-rendering back on the client (note: they will lose their call stack, but it can help point you in right direction)
327
-
328
254
## CoffeeScript
329
255
330
256
It is possible to use JSX with CoffeeScript. The caveat is that you will still need to include the docblock. Since CoffeeScript doesn't allow `/* */` style comments, we need to do something a little different. We also need to embed JSX inside backticks so CoffeeScript ignores the syntax it doesn't understand. Here's an example:
### Changing react.js and JSXTransformer.js versions
339
-
340
-
In some cases you may want to have your `react.js` and `JSXTransformer.js` files come from a different release than the one, that is specified in the `react-rails.gemspec`. To achieve that, you have to manually replace them in your app.
341
-
342
-
#### Instructions
343
-
344
-
Just put another version of `react.js` or `JSXTransformer.js` under `/vendor/assets/react` directory.
345
-
If you need different versions of `react.js` for production and development, then use a subdirectory named
346
-
after `config.react.variant`, e.g. you set `config.react.variant = :development` so for this environment
347
-
`react.js` is expected to be in `/vendor/assets/react/development`
348
-
349
-
#### Things to remember
350
-
351
-
If you replace `JSXTransformer.js` in production environment, you have to restart your rails instance,
352
-
because the jsx compiler context is cached.
353
-
354
-
Name of the `JSXTransformer.js` file *is case-sensitive*.
0 commit comments