Skip to content

Commit 7c85e4a

Browse files
committed
Merge remote-tracking branch 'upstream/master' into component-generator
2 parents 768e3ef + 5ad3c77 commit 7c85e4a

23 files changed

+139
-57
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
---
22
language: ruby
33
rvm:
4+
- 2.2
5+
- 2.1
46
- 2.0.0
57
- 1.9.3
68
- jruby-19mode
79
before_install:
810
- gem install bundler --version '>= 1.2.2'
9-
before_script: 'bundle exec rake appraisal:install'
11+
before_script: 'bundle exec appraisal install'
1012
script: 'bundle exec rake appraisal test'

README.md

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,11 @@ Alternatively, you can include it directly as a separate script tag:
5858

5959
### JSX
6060

61-
To transform your JSX into JS, simply create `.js.jsx` files, and ensure that the file has the `/** @jsx React.DOM */` docblock. These files will be transformed on request, or precompiled as part of the `assets:precompile` task.
61+
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.
6262

63-
CoffeeScript files can also be used, by creating `.js.jsx.coffee` files. You must use this form of the docblock at the top of each file: `###* @jsx React.DOM ###`. We also need to embed JSX inside backticks so CoffeeScript ignores the syntax it doesn't understand. Here's an example:
63+
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:
6464

6565
```coffee
66-
###* @jsx React.DOM ###
67-
6866
Component = React.createClass
6967
render: ->
7068
`<ExampleComponent videos={this.props.videos} />`
@@ -73,10 +71,10 @@ Component = React.createClass
7371

7472
### Unobtrusive JavaScript
7573

76-
`react_ujs` will call `React.renderComponent` for every element with `data-react-class` attribute. React properties can be specified by `data-react-props` attribute in JSON format. For example:
74+
`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:
7775

7876
```erb
79-
<!-- react_ujs will execute `React.renderComponent(HelloMessage({name:"Bob"}), element)` -->
77+
<!-- react_ujs will execute `React.render(HelloMessage({name:"Bob"}), element)` -->
8078
<div data-react-class="HelloMessage" data-react-props="<%= {name: 'Bob'}.to_json %>" />
8179
```
8280

@@ -111,6 +109,61 @@ react_component('HelloMessage', {name: 'John'}, {id: 'hello', class: 'foo', tag:
111109
# <span class="foo" id="hello" data-...></span>
112110
```
113111

112+
#### With JSON and Jbuilder
113+
114+
You can pass prepared JSON directly to the helper, as well.
115+
116+
```ruby
117+
react_component('HelloMessage', {name: 'John'}.to_json)
118+
# <div data-react-class="HelloMessage" data-react-props="{&quot;name&quot;:&quot;John&quot;}"></div>
119+
```
120+
121+
This is especially helpful if you are already using a tool like Jbuilder in your project.
122+
123+
```ruby
124+
# messages/show.json.jbuilder
125+
json.name name
126+
```
127+
128+
```ruby
129+
react_component('HelloMessage', render(template: 'messages/show.json.jbuilder', locals: {name: 'John'}))
130+
# <div data-react-class="HelloMessage" data-react-props="{&quot;name&quot;:&quot;John&quot;}"></div>
131+
```
132+
133+
##### Important Note
134+
135+
By default, the scaffolded Rails index jbuilder templates do not include a root-node. An example scaffolded index.json.jbuilder looks like this:
136+
137+
```ruby
138+
json.array!(@messages) do |message|
139+
json.extract! message, :id, :name
140+
json.url message_url(message, format: :json)
141+
end
142+
```
143+
144+
which generates JSON like this:
145+
146+
```json
147+
[{"id":1,"name":"hello","url":"http://localhost:3000/messages/1.json"},{"id":2,"name":"hello","url":"http://localhost:3000/messages/2.json"},{"id":3,"name":"hello","url":"http://localhost:3000/messages/3.json"}]
148+
```
149+
150+
This is not suitable for ReactJS props, which is expected to be a key-value object. You will need to wrap your index.json.jbuilder node with a root node, like so:
151+
152+
```ruby
153+
json.messages do |json|
154+
json.array!(@messages) do |message|
155+
json.extract! message, :id, :name
156+
json.url message_url(message, format: :json)
157+
end
158+
end
159+
```
160+
161+
Which will generate:
162+
163+
```json
164+
{"messages":[{"id":1,"name":"hello","url":"http://localhost:3000/messages/1.json"},{"id":2,"name":"hello","url":"http://localhost:3000/messages/2.json"},{"id":3,"name":"hello","url":"http://localhost:3000/messages/3.json"}]}
165+
```
166+
114167
### Server Rendering
115168

116169
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.
@@ -136,8 +189,6 @@ In order for us to render your React components, we need to be able to find them
136189
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:
137190

138191
```coffee
139-
###* @jsx React.DOM ###
140-
141192
Component = React.createClass
142193
render: ->
143194
`<ExampleComponent videos={this.props.videos} />`
@@ -257,8 +308,6 @@ end
257308
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:
258309

259310
```coffee
260-
###* @jsx React.DOM ###
261-
262311
Component = React.createClass
263312
render: ->
264313
`<ExampleComponent videos={this.props.videos} />`

Rakefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Rake::TestTask.new(:test) do |t|
1414
t.libs << 'test'
1515
t.pattern = ENV['TEST_PATTERN'] || 'test/**/*_test.rb'
1616
t.verbose = ENV['TEST_VERBOSE'] == '1'
17+
t.warning = true
1718
end
1819

1920
task default: :test

gemfiles/rails_3.1.gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ source "http://rubygems.org"
55
gem "rails", "~> 3.1"
66
gem "sprockets", ">= 2.2.2"
77

8-
gemspec :path=>"../"
8+
gemspec :path => "../"

gemfiles/rails_3.2.gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ source "http://rubygems.org"
44

55
gem "rails", "~> 3.2"
66

7-
gemspec :path=>"../"
7+
gemspec :path => "../"

gemfiles/rails_4.0.gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ source "http://rubygems.org"
44

55
gem "rails", "~> 4.0"
66

7-
gemspec :path=>"../"
7+
gemspec :path => "../"

gemfiles/rails_4.0_with_therubyracer.gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
source "http://rubygems.org"
44

55
gem "rails", "~> 4.0"
6-
gem "therubyracer", "0.12.0", :platform=>:mri
6+
gem "therubyracer", "0.12.0", :platform => :mri
77

8-
gemspec :path=>"../"
8+
gemspec :path => "../"

gemfiles/rails_4.1.gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ source "http://rubygems.org"
44

55
gem "rails", "~> 4.1"
66

7-
gemspec :path=>"../"
7+
gemspec :path => "../"

lib/assets/javascripts/react_ujs.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
var constructor = window[className] || eval.call(window, className);
2626
var propsJson = node.getAttribute(PROPS_ATTR);
2727
var props = propsJson && JSON.parse(propsJson);
28-
React.renderComponent(constructor(props), node);
28+
React.render(React.createElement(constructor, props), node);
2929
}
3030
};
3131

lib/react/rails/view_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def react_component(name, args = {}, options = {}, &block)
1313
html_options = options.reverse_merge(:data => {})
1414
html_options[:data].tap do |data|
1515
data[:react_class] = name
16-
data[:react_props] = args.to_json unless args.empty?
16+
data[:react_props] = React::Renderer.react_props(args) unless args.empty?
1717
end
1818
html_tag = html_options[:tag] || :div
1919

0 commit comments

Comments
 (0)