Skip to content

Commit 9e2cc9d

Browse files
committed
Merge branch 'master' into chore/update-appraisals
2 parents 0715043 + 649e2d6 commit 9e2cc9d

File tree

12 files changed

+126
-39
lines changed

12 files changed

+126
-39
lines changed

README.md

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
[![Gem](https://img.shields.io/gem/v/react-rails.svg?style=flat-square)](http://rubygems.org/gems/react-rails)
44
[![npm](https://img.shields.io/npm/v/react_ujs.svg?style=flat-square)](https://www.npmjs.com/package/react_ujs)
55
[![Build Status](https://img.shields.io/travis/reactjs/react-rails/master.svg?style=flat-square)](https://travis-ci.org/reactjs/react-rails)
6-
[![Code Climate](https://img.shields.io/codeclimate/github/reactjs/react-rails.svg?style=flat-square)](https://codeclimate.com/github/reactjs/react-rails)
6+
[![Maintainers Wanted](https://img.shields.io/badge/Maintainers-Wanted-red.svg)
77

88

9-
React-Rails is a flexible tool to use [React](http://facebook.github.io/react/) with Rails. It:
9+
React-Rails is a flexible tool to use [React](http://facebook.github.io/react/) with Rails. The benefits:
1010
* Automatically renders React server-side and client-side
1111
* Supports Webpacker 3.x, 2.x, 1.1+
1212
* Supports Sprockets 4.x, 3.x, 2.x
1313
* Lets you use [JSX](http://facebook.github.io/react/docs/jsx-in-depth.html), [ES6](http://es6-features.org/), [TypeScript](https://www.typescriptlang.org/), [CoffeeScript](http://coffeescript.org/)
1414

15-
Example app code available here: https://github.com/BookOfGreg/react-rails-example-app
15+
A source code example utilizing React-Rails: https://github.com/BookOfGreg/react-rails-example-app
1616

1717
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
1818
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
@@ -46,30 +46,30 @@ Example app code available here: https://github.com/BookOfGreg/react-rails-examp
4646
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
4747

4848

49-
The React-Rails Wiki has lots of additional information about React-Rails including many "how-to" articles and answers to the most frequently asked questions. Please browse the Wiki after finishing this README:
50-
49+
After reading this README file, additional information about React-Rails can be found in the Wiki page:
5150
https://github.com/reactjs/React-Rails/wiki
51+
The Wiki page features a significant amount of additional information about React-Rails which includes instructional articles and answers to the most frequently asked questions.
5252

5353

5454
## Get started with Webpacker
5555

56-
[or Get started with Sprockets](#use-with-asset-pipeline)
56+
[Alternatively, get started with Sprockets](#use-with-asset-pipeline)
5757

58-
[Webpacker](https://github.com/rails/webpacker) integrates modern JS tooling with Rails.
58+
[Webpacker](https://github.com/rails/webpacker) provides modern JS tooling for Rails. Here are the listed steps for integrating Webpacker and Rails-React with Rails:
5959

60-
1) Create a new Rails app:
60+
##### 1) Create a new Rails app:
6161
```
6262
$ rails new my-app
6363
$ cd my-app
6464
```
6565

66-
2) Add `webpacker` and `react-rails` to your gemfile
66+
##### 2) Add `webpacker` and `react-rails` to your gemfile:
6767
```
6868
gem 'webpacker'
6969
gem 'react-rails'
7070
```
7171

72-
3) Now run the installers:
72+
##### 3) Now run the installers:
7373
```
7474
$ bundle install
7575
$ rails webpacker:install # OR (on rails version < 5.0) rake webpacker:install
@@ -82,37 +82,39 @@ This gives you:
8282
- [`ReactRailsUJS`](#ujs) setup in `app/javascript/packs/application.js`
8383
- `app/javascript/packs/server_rendering.js` for [server-side rendering](#server-side-rendering)
8484

85-
4) Link the JavaScript pack in Rails view using `javascript_pack_tag` [helper](https://github.com/rails/webpacker#usage), for example:
85+
##### 4) Link the JavaScript pack in Rails view using `javascript_pack_tag` [helper](https://github.com/rails/webpacker#usage):
8686
```
8787
<!-- application.html.erb in Head tag below turbolinks -->
8888
<%= javascript_pack_tag 'application' %>
8989
```
9090

91-
5) Generate your first component:
91+
##### 5) Generate your first component:
9292
```
9393
$ rails g react:component HelloWorld greeting:string
9494
```
9595

96-
6) You can also generate your component in a subdirectory:
96+
##### 6) You can also generate your component in a subdirectory:
9797
```
9898
$ rails g react:component my_subdirectory/HelloWorld greeting:string
9999
```
100100
Note: Your component is added to `app/javascript/components/` by default.
101101

102102

103-
7) [Render it in a Rails view](#view-helper):
103+
##### 7) [Render it in a Rails view](#view-helper):
104104

105105
```
106106
<!-- erb: paste this in view -->
107107
<%= react_component("HelloWorld", { greeting: "Hello from react-rails." }) %>
108108
```
109109

110-
8) Lets Start the app:
110+
##### 8) Lets Start the app:
111111
```
112112
$ rails s
113113
```
114114
output: greeting: Hello from react-rails", inspect webpage in your browser too see change in tag props.
115115

116+
### Component name
117+
116118
The component name tells `react-rails` where to load the component. For example:
117119

118120
`react_component` call | component `require`
@@ -157,9 +159,44 @@ $ yarn add @types/react @types/react-dom
157159

158160
Doing this will allow React-Rails to support the .tsx extension.
159161

162+
### Test component
163+
164+
You can use `assert_react_component` to test component render:
165+
166+
app/views/welcome/index.html.erb
167+
168+
```erb
169+
<%= react_component("HelloWorld", { greeting: "Hello from react-rails.", info: { name: "react-rails" } }, { class: "hello-world" }) %>
170+
```
171+
172+
```rb
173+
class WelcomeControllerTest < ActionDispatch::IntegrationTest
174+
test 'assert_react_component' do
175+
get "/welcome"
176+
assert_equal 200, response.status
177+
178+
# assert rendered react component and check the props
179+
assert_react_component "HelloWorld" do |props|
180+
assert_equal "Hello from react-rails.", props[:greeting]
181+
assert_equal "react-rails", props[:info][:name]
182+
assert_select "[class=?]", "hello-world"
183+
end
184+
185+
# or just assert component rendered
186+
assert_react_component "HelloWorld"
187+
end
188+
end
189+
```
190+
160191
## Use with Asset Pipeline
161192

162-
`react-rails` provides a pre-bundled React.js & a UJS driver to the Rails asset pipeline. Get started by installing:
193+
`react-rails` provides a pre-bundled React.js & a UJS driver to the Rails asset pipeline. Get started by adding the `react-rails` gem:
194+
195+
```
196+
gem 'react-rails'
197+
```
198+
199+
And then install the react generator:
163200

164201
```
165202
$ rails g react:install

lib/generators/react/install_generator.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def create_directory
2525
end
2626
empty_directory File.join(components_dir, 'components')
2727
unless options[:skip_git]
28-
create_file File.join(components_dir, 'components/.gitkeep')
28+
create_file File.join(components_dir, 'components/.keep')
2929
end
3030
end
3131

@@ -96,9 +96,9 @@ def setup_react_sprockets
9696

9797
WEBPACKER_SETUP_UJS = <<-JS
9898
// Support component names relative to this directory:
99-
var componentRequireContext = require.context("components", true)
100-
var ReactRailsUJS = require("react_ujs")
101-
ReactRailsUJS.useContext(componentRequireContext)
99+
var componentRequireContext = require.context("components", true);
100+
var ReactRailsUJS = require("react_ujs");
101+
ReactRailsUJS.useContext(componentRequireContext);
102102
JS
103103

104104
def setup_react_webpacker
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// By default, this pack is loaded for server-side rendering.
22
// It must expose react_ujs as `ReactRailsUJS` and prepare a require context.
3-
var componentRequireContext = require.context("components", true)
4-
var ReactRailsUJS = require("react_ujs")
5-
ReactRailsUJS.useContext(componentRequireContext)
3+
var componentRequireContext = require.context("components", true);
4+
var ReactRailsUJS = require("react_ujs");
5+
ReactRailsUJS.useContext(componentRequireContext);

lib/react-rails.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,9 @@
22
require 'react/jsx'
33
require 'react/rails'
44
require 'react/server_rendering'
5+
6+
module React
7+
module Rails
8+
autoload :TestHelper, 'react/rails/test_helper'
9+
end
10+
end

lib/react/rails/railtie.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class Railtie < ::Rails::Railtie
5858

5959
ActiveSupport.on_load(:action_view) do
6060
include ::React::Rails::ViewHelper
61+
ActionDispatch::IntegrationTest.send(:include, React::Rails::TestHelper)
6162
end
6263
end
6364

lib/react/rails/test_helper.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module React
2+
module Rails
3+
module TestHelper
4+
extend ActiveSupport::Concern
5+
6+
# assert react_component render
7+
#
8+
# assert_react_component("HelloWorld") do |props|
9+
# assert_equal "Hello world", props[:message]
10+
# end
11+
def assert_react_component(name)
12+
assert_select "div[data-react-class]" do |dom|
13+
assert_select "[data-react-class=?]", name
14+
15+
if block_given?
16+
props = JSON.parse(dom.attr("data-react-props"))
17+
props.deep_transform_keys! { |key| key.to_s.underscore }
18+
props.deep_symbolize_keys!
19+
20+
yield(props)
21+
end
22+
end
23+
end
24+
end
25+
end
26+
end

test/dummy_sprockets/app/views/pages/show.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
</ul>
55

66
<div id='component-parent'>
7-
<%= react_component 'GreetingMessage', { name: @name }, { id: 'component', prerender: @prerender } %>
7+
<%= react_component 'GreetingMessage', { name: @name, last_name: "Last #{@name}", info: { name: @name } }, { id: 'component', class: "greeting-message", prerender: @prerender } %>
88
<ul>
99
<%= react_component 'Todo', { todo: 'Another Component' }, { id: 'todo', prerender: @prerender } %>
1010
</ul>
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// By default, this pack is loaded for server-side rendering.
22
// It must expose react_ujs as `ReactRailsUJS` and prepare a require context.
3-
var componentRequireContext = require.context("components", true)
4-
var ReactRailsUJS = require("../../../../../react_ujs/index")
5-
ReactRailsUJS.useContext(componentRequireContext)
3+
var componentRequireContext = require.context("components", true);
4+
var ReactRailsUJS = require("../../../../../react_ujs/index");
5+
ReactRailsUJS.useContext(componentRequireContext);
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// By default, this pack is loaded for server-side rendering.
22
// It must expose react_ujs as `ReactRailsUJS` and prepare a require context.
3-
var componentRequireContext = require.context("components", true)
4-
var ReactRailsUJS = require("react_ujs")
5-
ReactRailsUJS.useContext(componentRequireContext)
3+
var componentRequireContext = require.context("components", true);
4+
var ReactRailsUJS = require("react_ujs");
5+
ReactRailsUJS.useContext(componentRequireContext);
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// By default, this pack is loaded for server-side rendering.
22
// It must expose react_ujs as `ReactRailsUJS` and prepare a require context.
3-
var componentRequireContext = require.context("components", true)
4-
var ReactRailsUJS = require("react_ujs")
5-
ReactRailsUJS.useContext(componentRequireContext)
3+
var componentRequireContext = require.context("components", true);
4+
var ReactRailsUJS = require("react_ujs");
5+
ReactRailsUJS.useContext(componentRequireContext);

test/generators/install_generator_webpacker_test.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ class InstallGeneratorWebpackerTest < Rails::Generators::TestCase
88
setup :prepare_destination
99

1010
EXPECTED_SETUP = %|// Support component names relative to this directory:
11-
var componentRequireContext = require.context("components", true)
12-
var ReactRailsUJS = require("react_ujs")
13-
ReactRailsUJS.useContext(componentRequireContext)
11+
var componentRequireContext = require.context("components", true);
12+
var ReactRailsUJS = require("react_ujs");
13+
ReactRailsUJS.useContext(componentRequireContext);
1414
|
1515

1616
DEFAULT_SERVER_RENDERING_PACK_PATH = 'app/javascript/packs/server_rendering.js'
@@ -32,9 +32,9 @@ def copy_directory(dir)
3232
test 'creates server_rendering.js with default requires' do
3333
run_generator
3434
assert_file DEFAULT_SERVER_RENDERING_PACK_PATH do |contents|
35-
assert_includes contents, "var componentRequireContext = require.context(\"components\", true)\n"
36-
assert_includes contents, "var ReactRailsUJS = require(\"react_ujs\")\n"
37-
assert_includes contents, "ReactRailsUJS.useContext(componentRequireContext)\n"
35+
assert_includes contents, "var componentRequireContext = require.context(\"components\", true);\n"
36+
assert_includes contents, "var ReactRailsUJS = require(\"react_ujs\");\n"
37+
assert_includes contents, "ReactRailsUJS.useContext(componentRequireContext);\n"
3838
end
3939
end
4040

test/react/rails/test_helper_test.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
require 'test_helper'
2+
3+
class TestHelperTest < ActionDispatch::IntegrationTest
4+
test 'assert_react_component' do
5+
get "/pages/1"
6+
assert_equal 200, response.status
7+
assert_react_component "GreetingMessage"
8+
assert_react_component "GreetingMessage" do |props|
9+
assert_equal "Bob", props[:name]
10+
assert_equal "Last Bob", props[:last_name]
11+
assert_equal "Bob", props[:info][:name]
12+
13+
assert_select "[id=?]", "component"
14+
assert_select "[class=?]", "greeting-message"
15+
end
16+
end
17+
end

0 commit comments

Comments
 (0)