react_on_rails 1.0.0.pre → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dockerignore +2 -0
- data/.eslintignore +2 -0
- data/.eslintrc +1 -0
- data/.gitignore +4 -0
- data/.jscsrc +2 -2
- data/.rubocop.yml +2 -0
- data/.scss-lint.yml +3 -3
- data/.travis.yml +31 -18
- data/Dockerfile_ci +12 -0
- data/Dockerfile_tests +12 -0
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +170 -290
- data/Rakefile +20 -7
- data/app/helpers/react_on_rails_helper.rb +5 -5
- data/docker-compose.yml +12 -0
- data/docs/Contributing.md +26 -2
- data/docs/gen-notes/react_syntax.md +3 -0
- data/docs/gen-notes/reducers.md +31 -0
- data/docs/generator_testing_script.md +50 -0
- data/docs/linters.md +8 -0
- data/docs/manual_configuration.md +202 -0
- data/docs/node_dependencies_and_npm.md +29 -0
- data/lib/generators/react_on_rails/base_generator.rb +116 -0
- data/lib/generators/react_on_rails/bootstrap_generator.rb +84 -0
- data/lib/generators/react_on_rails/generator_helper.rb +48 -0
- data/lib/generators/react_on_rails/heroku_deployment_generator.rb +22 -0
- data/lib/generators/react_on_rails/install_generator.rb +86 -0
- data/lib/generators/react_on_rails/linters_generator.rb +38 -0
- data/lib/generators/react_on_rails/react_no_redux_generator.rb +37 -0
- data/lib/generators/react_on_rails/react_with_redux_generator.rb +61 -0
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev.tt +4 -0
- data/lib/generators/react_on_rails/templates/base/base/REACT_ON_RAILS.md +16 -0
- data/lib/generators/react_on_rails/templates/base/base/app/controllers/hello_world_controller.rb +5 -0
- data/lib/generators/react_on_rails/templates/base/base/app/views/hello_world/index.html.erb.tt +6 -0
- data/lib/generators/react_on_rails/templates/base/base/client/.babelrc +3 -0
- data/lib/generators/react_on_rails/templates/base/base/client/REACT_ON_RAILS_CLIENT_README.md +3 -0
- data/lib/generators/react_on_rails/templates/base/base/client/app/bundles/HelloWorld/startup/clientGlobals.jsx +4 -0
- data/lib/generators/react_on_rails/templates/base/base/client/index.jade +15 -0
- data/lib/generators/react_on_rails/templates/base/base/client/npm-shrinkwrap.json +2907 -0
- data/lib/generators/react_on_rails/templates/base/base/client/server.js +58 -0
- data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.base.config.js +58 -0
- data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.hot.config.js +65 -0
- data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.rails.config.js +45 -0
- data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +30 -0
- data/lib/generators/react_on_rails/templates/base/base/lib/tasks/assets.rake +26 -0
- data/lib/generators/react_on_rails/templates/base/base/package.json +31 -0
- data/lib/generators/react_on_rails/templates/base/server_rendering/client/app/bundles/HelloWorld/startup/serverGlobals.jsx +3 -0
- data/lib/generators/react_on_rails/templates/base/server_rendering/client/webpack.server.rails.config.js +37 -0
- data/lib/generators/react_on_rails/templates/bootstrap/app/assets/stylesheets/_bootstrap-custom.scss +63 -0
- data/lib/generators/react_on_rails/templates/bootstrap/client/assets/stylesheets/_post-bootstrap.scss +10 -0
- data/lib/generators/react_on_rails/templates/bootstrap/client/assets/stylesheets/_pre-bootstrap.scss +8 -0
- data/lib/generators/react_on_rails/templates/bootstrap/client/assets/stylesheets/_react-on-rails-sass-helper.scss +19 -0
- data/lib/generators/react_on_rails/templates/bootstrap/client/bootstrap-sass.config.js +89 -0
- data/lib/generators/react_on_rails/templates/client/README.md +97 -0
- data/lib/generators/react_on_rails/templates/heroku_deployment/.buildpacks +2 -0
- data/lib/generators/react_on_rails/templates/heroku_deployment/Procfile +1 -0
- data/lib/generators/react_on_rails/templates/linters/client/.eslintignore +1 -0
- data/lib/generators/react_on_rails/templates/linters/client/.eslintrc +17 -0
- data/lib/generators/react_on_rails/templates/linters/client/.jscsrc +7 -0
- data/lib/generators/react_on_rails/templates/linters/lib/tasks/brakeman.rake +17 -0
- data/lib/generators/react_on_rails/templates/linters/lib/tasks/ci.rake +33 -0
- data/lib/generators/react_on_rails/templates/linters/lib/tasks/linters.rake +81 -0
- data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx +39 -0
- data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/containers/HelloWorld.jsx +33 -0
- data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/startup/HelloWorldAppClient.jsx +11 -0
- data/lib/generators/react_on_rails/templates/no_redux/base/client/package.json.tt +75 -0
- data/lib/generators/react_on_rails/templates/no_redux/server_rendering/client/app/bundles/HelloWorld/startup/HelloWorldAppServer.jsx +11 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/actions/helloWorldActionCreators.jsx +8 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx +48 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/constants/helloWorldConstants.jsx +8 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/containers/HelloWorld.jsx +43 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/reducers/helloWorldReducer.jsx +21 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/reducers/index.jsx +14 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/HelloWorldAppClient.jsx +20 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/store/helloWorldStore.jsx +35 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/lib/middlewares/loggerMiddleware.js +25 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/package.json.tt +82 -0
- data/lib/generators/react_on_rails/templates/redux/server_rendering/client/app/bundles/HelloWorld/startup/HelloWorldAppServer.jsx +21 -0
- data/lib/react_on_rails.rb +1 -7
- data/lib/react_on_rails/configuration.rb +14 -5
- data/lib/react_on_rails/engine.rb +7 -0
- data/lib/react_on_rails/server_rendering_pool.rb +14 -1
- data/lib/react_on_rails/version.rb +1 -1
- data/react_on_rails.gemspec +2 -2
- data/ruby-lint.yml +1 -0
- metadata +75 -11
- data/Dockerfile +0 -14
- data/docs/README.md +0 -1
@@ -0,0 +1,19 @@
|
|
1
|
+
// The Rails server imports this file via app/assets/stylesheets/application.css.scss
|
2
|
+
// The webpack HMR dev server loads this file via client/bootstrap-sass.config.js
|
3
|
+
|
4
|
+
// This file allows the same sass code with Rails and node-sass for the Webpack Dev Server.
|
5
|
+
// It is CRTICAL that this file is loaded first.
|
6
|
+
|
7
|
+
$rails: false !default; // defaults to false (e.g. webpack environment)
|
8
|
+
|
9
|
+
// Sass 3 removes image-url helper
|
10
|
+
// https://github.com/sass/libsass/issues/489
|
11
|
+
$image-url-path: '/assets/images/' !default;
|
12
|
+
|
13
|
+
@function img-url($image) {
|
14
|
+
@if $rails {
|
15
|
+
@return image-url($image);
|
16
|
+
} @else {
|
17
|
+
@return url('#{$image-url-path}#{$image}');
|
18
|
+
}
|
19
|
+
}
|
@@ -0,0 +1,89 @@
|
|
1
|
+
// See https://github.com/shakacode/bootstrap-sass-loader for more information
|
2
|
+
|
3
|
+
// IMPORTANT: Make sure to keep the customizations defined in this file
|
4
|
+
// in-sync with the ones defined in app/assets/stylesheets/_bootstrap-custom.scss.
|
5
|
+
|
6
|
+
// For a reference on customizations,refer to:
|
7
|
+
// https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/_bootstrap.scss
|
8
|
+
|
9
|
+
module.exports = {
|
10
|
+
bootstrapCustomizations: './assets/stylesheets/_pre-bootstrap.scss',
|
11
|
+
mainSass: './assets/stylesheets/_post-bootstrap.scss',
|
12
|
+
|
13
|
+
// Default for the style loading is to put in your js files
|
14
|
+
// styleLoader: 'style-loader!css-loader!sass-loader',
|
15
|
+
|
16
|
+
// See: https://github.com/sass/node-sass#outputstyle
|
17
|
+
// https://github.com/sass/node-sass#imagepath
|
18
|
+
styleLoader: 'style-loader!css-loader!sass-loader?imagePath=/assets/images',
|
19
|
+
|
20
|
+
// ### Scripts
|
21
|
+
// Any scripts here set to false will never make it to the client,
|
22
|
+
// i.e. it's not packaged by webpack.
|
23
|
+
scripts: {
|
24
|
+
transition: true,
|
25
|
+
alert: true,
|
26
|
+
button: true,
|
27
|
+
|
28
|
+
carousel: true,
|
29
|
+
collapse: true,
|
30
|
+
dropdown: true,
|
31
|
+
|
32
|
+
modal: true,
|
33
|
+
tooltip: true,
|
34
|
+
popover: true,
|
35
|
+
scrollspy: true,
|
36
|
+
tab: true,
|
37
|
+
affix: true,
|
38
|
+
},
|
39
|
+
|
40
|
+
// ### Styles
|
41
|
+
// Enable or disable certain less components and thus remove
|
42
|
+
// the css for them from the build.
|
43
|
+
styles: {
|
44
|
+
mixins: true,
|
45
|
+
|
46
|
+
normalize: true,
|
47
|
+
print: true,
|
48
|
+
|
49
|
+
scaffolding: true,
|
50
|
+
type: true,
|
51
|
+
code: true,
|
52
|
+
grid: true,
|
53
|
+
tables: true,
|
54
|
+
forms: true,
|
55
|
+
buttons: true,
|
56
|
+
|
57
|
+
'component-animations': true,
|
58
|
+
glyphicons: true,
|
59
|
+
dropdowns: true,
|
60
|
+
'button-groups': true,
|
61
|
+
'input-groups': true,
|
62
|
+
navs: true,
|
63
|
+
navbar: true,
|
64
|
+
breadcrumbs: true,
|
65
|
+
pagination: true,
|
66
|
+
pager: true,
|
67
|
+
labels: true,
|
68
|
+
badges: true,
|
69
|
+
|
70
|
+
jumbotron: true,
|
71
|
+
thumbnails: true,
|
72
|
+
alerts: true,
|
73
|
+
|
74
|
+
'progress-bars': true,
|
75
|
+
media: true,
|
76
|
+
'list-group': true,
|
77
|
+
panels: true,
|
78
|
+
wells: true,
|
79
|
+
close: true,
|
80
|
+
|
81
|
+
modals: true,
|
82
|
+
tooltip: true,
|
83
|
+
popovers: true,
|
84
|
+
carousel: true,
|
85
|
+
|
86
|
+
utilities: true,
|
87
|
+
'responsive-utilities': true,
|
88
|
+
},
|
89
|
+
};
|
@@ -0,0 +1,97 @@
|
|
1
|
+
Example NPM Package
|
2
|
+
===========================
|
3
|
+
We've included an example package.json from https://github.com/shakacode/react-webpack-rails-tutorial which should get you started with your React project.
|
4
|
+
|
5
|
+
Starting the node.js server:
|
6
|
+
```
|
7
|
+
npm start
|
8
|
+
```
|
9
|
+
|
10
|
+
Building client javascript files for production:
|
11
|
+
```
|
12
|
+
npm run build:client
|
13
|
+
```
|
14
|
+
|
15
|
+
Building server javascript files for production:
|
16
|
+
```
|
17
|
+
npm run build:server
|
18
|
+
```
|
19
|
+
|
20
|
+
Building client javascript files for development:
|
21
|
+
```
|
22
|
+
npm run build:dev:client
|
23
|
+
```
|
24
|
+
|
25
|
+
Building server javascript files for development:
|
26
|
+
```
|
27
|
+
npm run build:dev:server
|
28
|
+
```
|
29
|
+
|
30
|
+
Running all linters:
|
31
|
+
```
|
32
|
+
npm run lint
|
33
|
+
```
|
34
|
+
|
35
|
+
Running eslint:
|
36
|
+
```
|
37
|
+
npm run eslint
|
38
|
+
```
|
39
|
+
|
40
|
+
Running jscs:
|
41
|
+
```
|
42
|
+
npm run jscs
|
43
|
+
```
|
44
|
+
|
45
|
+
dependencies vs devDependencies
|
46
|
+
===========================
|
47
|
+
Anything needed for heroku deployment needs to go in "dependencies", and anything not needed for heroku deployment should go in "devDependencies".
|
48
|
+
|
49
|
+
|
50
|
+
Updating Node Dependencies
|
51
|
+
===========================
|
52
|
+
|
53
|
+
```
|
54
|
+
npm install -g npm-check-updates
|
55
|
+
```
|
56
|
+
|
57
|
+
Then run this to update the dependencies (starting at the top level).
|
58
|
+
|
59
|
+
```
|
60
|
+
# Make sure you are in the top directory, then run:
|
61
|
+
cd client
|
62
|
+
rm npm-shrinkwrap.json
|
63
|
+
npm-check-updates -u
|
64
|
+
npm install
|
65
|
+
npm prune
|
66
|
+
npm shrinkwrap
|
67
|
+
```
|
68
|
+
|
69
|
+
Then confirm that the hot reload server and the rails server both work fine. You
|
70
|
+
may have to delete `node_modules` and `npm-shrinkwrap.json` and then run `npm
|
71
|
+
shrinkwrap`.
|
72
|
+
|
73
|
+
Note: `npm prune` is required before running `npm shrinkwrap` to remove dependencies that are no longer needed after doing updates.
|
74
|
+
|
75
|
+
|
76
|
+
Adding Node Modules
|
77
|
+
=====================================
|
78
|
+
Suppose you want to add a dependency to "module_name"....
|
79
|
+
|
80
|
+
Before you do so, consider:
|
81
|
+
|
82
|
+
1. Do we really need the module and the extra JS code?
|
83
|
+
2. Is the module well maintained?
|
84
|
+
|
85
|
+
```bash
|
86
|
+
cd client
|
87
|
+
npm install --save module_name@version
|
88
|
+
# or
|
89
|
+
# npm install --save_dev module_name@version
|
90
|
+
rm npm-shrinkwrap.json
|
91
|
+
npm shrinkwrap
|
92
|
+
```
|
93
|
+
|
94
|
+
Setting Up a Basic REST API
|
95
|
+
=====================================
|
96
|
+
See server.js in our tutorial at
|
97
|
+
https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/server.js
|
@@ -0,0 +1 @@
|
|
1
|
+
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
|
@@ -0,0 +1 @@
|
|
1
|
+
node_modules
|
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
parser: babel-eslint
|
3
|
+
|
4
|
+
extends: eslint-config-airbnb
|
5
|
+
|
6
|
+
plugins:
|
7
|
+
- react
|
8
|
+
|
9
|
+
env:
|
10
|
+
browser: true
|
11
|
+
node: true
|
12
|
+
|
13
|
+
rules:
|
14
|
+
indent: [1, 2, { SwitchCase: 1, VariableDeclarator: 2 }]
|
15
|
+
react/sort-comp: 0
|
16
|
+
react/jsx-quotes: 1
|
17
|
+
id-length: [2, {"exceptions": ["e", "i"]}]
|
@@ -0,0 +1,17 @@
|
|
1
|
+
namespace :brakeman do
|
2
|
+
|
3
|
+
desc "Run Brakeman"
|
4
|
+
task :run, :output_files do |t, args|
|
5
|
+
require 'brakeman'
|
6
|
+
|
7
|
+
files = args[:output_files].split(' ') if args[:output_files]
|
8
|
+
Brakeman.run :app_path => ".", :output_files => files, :print_report => true
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Check your code with Brakeman"
|
12
|
+
task :check do
|
13
|
+
require 'brakeman'
|
14
|
+
result = Brakeman.run app_path: '.', print_report: true
|
15
|
+
exit Brakeman::Warnings_Found_Exit_Code unless result.filtered_warnings.empty?
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
if Rails.env.development?
|
2
|
+
# See tasks/linters.rake
|
3
|
+
|
4
|
+
task :bundle_audit do
|
5
|
+
puts Rainbow("Running security audit on gems (bundle_audit)").green
|
6
|
+
Rake::Task["bundle_audit"].invoke
|
7
|
+
end
|
8
|
+
|
9
|
+
task :security_audit do
|
10
|
+
puts Rainbow("Running security audit on code (brakeman)").green
|
11
|
+
|
12
|
+
sh "brakeman --exit-on-warn --quiet -A -z"
|
13
|
+
end
|
14
|
+
|
15
|
+
namespace :ci do
|
16
|
+
desc "Run all audits and tests"
|
17
|
+
task all: [:environment, :lint, :spec, :bundle_audit, :security_audit] do
|
18
|
+
begin
|
19
|
+
puts Rainbow("PASSED").green
|
20
|
+
puts ""
|
21
|
+
rescue Exception => e
|
22
|
+
puts "#{e}"
|
23
|
+
puts Rainbow("FAILED").red
|
24
|
+
puts ""
|
25
|
+
raise(e)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
task ci: "ci:all"
|
31
|
+
|
32
|
+
task(:default).clear.enhance([:ci])
|
33
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
if %w(development test).include? Rails.env
|
2
|
+
namespace :lint do
|
3
|
+
# This fails: https://github.com/bbatsov/rubocop/issues/1840
|
4
|
+
# RuboCop::RakeTask.new
|
5
|
+
# require "rubocop/rake_task"
|
6
|
+
desc "Run Rubocop lint in shell. Specify option fix to auto-correct (and don't have uncommitted files!)."
|
7
|
+
task :rubocop, [:fix] => [] do |_t, args|
|
8
|
+
def to_bool(str)
|
9
|
+
return true if str =~ (/^(true|t|yes|y|1)$/i)
|
10
|
+
return false if str.blank? || str =~ (/^(false|f|no|n|0)$/i)
|
11
|
+
fail ArgumentError, "invalid value for Boolean: \"#{str}\""
|
12
|
+
end
|
13
|
+
|
14
|
+
fix = (args.fix == "fix") || to_bool(args.fix)
|
15
|
+
cmd = "rubocop -S -D#{fix ? ' -a' : ''} ."
|
16
|
+
puts "Running Rubocop Linters via `#{cmd}`#{fix ? ' auto-correct is turned on!' : ''}"
|
17
|
+
sh cmd
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Run ruby-lint as shell"
|
21
|
+
task :ruby do
|
22
|
+
cmd = "ruby-lint app config spec lib"
|
23
|
+
puts "Running ruby-lint Linters via `#{cmd}`"
|
24
|
+
sh cmd
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "eslint"
|
28
|
+
task :eslint do
|
29
|
+
cmd = "cd client && npm run eslint . -- --ext .jsx,.js"
|
30
|
+
puts "Running eslint via `#{cmd}`"
|
31
|
+
sh cmd
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "jscs"
|
35
|
+
task :jscs do
|
36
|
+
cmd = "cd client && npm run jscs ."
|
37
|
+
puts "Running jscs via `#{cmd}`"
|
38
|
+
sh cmd
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "JS Linting"
|
42
|
+
task js: [:eslint, :jscs] do
|
43
|
+
puts "Completed running all JavaScript Linters"
|
44
|
+
end
|
45
|
+
|
46
|
+
# desc "haml_lint"
|
47
|
+
# task :haml_lint do
|
48
|
+
# require 'haml_lint/rake_task'
|
49
|
+
|
50
|
+
# HamlLint::RakeTask.new do |t|
|
51
|
+
# t.files = ["app/views"]
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
|
55
|
+
# desc "See docs for task 'slim_lint'"
|
56
|
+
# task slim: :slim_lint
|
57
|
+
# SlimLint::RakeTask.new do |t|
|
58
|
+
# t.files = ["app/views"]
|
59
|
+
# end
|
60
|
+
|
61
|
+
desc "See docs for task 'scss_lint'"
|
62
|
+
task :scss do
|
63
|
+
begin
|
64
|
+
require 'scss_lint/rake_task'
|
65
|
+
SCSSLint::RakeTask.new do |t|
|
66
|
+
t.files = ["app/assets/stylesheets/", "client/assets/stylesheets/"]
|
67
|
+
end
|
68
|
+
Rake::Task[:scss_lint].invoke
|
69
|
+
rescue LoadError
|
70
|
+
puts "** add gem 'scss_lint' to your Gemfile for scss linting."
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
task lint: [:rubocop, :ruby, :js, :scss] do
|
75
|
+
puts "Completed all linting"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Runs all linters. Run `rake -D lint` to see all available lint options"
|
80
|
+
task lint: ["lint:lint"]
|
81
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import React, { PropTypes } from 'react';
|
2
|
+
import _ from 'lodash';
|
3
|
+
|
4
|
+
// Simple example of a React "dumb" component
|
5
|
+
export default class HelloWorldWidget extends React.Component {
|
6
|
+
constructor(props, context) {
|
7
|
+
super(props, context);
|
8
|
+
|
9
|
+
// Uses lodash to bind all methods to the context of the object instance, otherwise
|
10
|
+
// the methods defined here would not refer to the component's class, not the component
|
11
|
+
// instance itself.
|
12
|
+
_.bindAll(this, '_handleChange');
|
13
|
+
}
|
14
|
+
|
15
|
+
static propTypes = {
|
16
|
+
name: PropTypes.string.isRequired,
|
17
|
+
_updateName: PropTypes.func.isRequired,
|
18
|
+
};
|
19
|
+
|
20
|
+
// React will automatically provide us with the event `e`
|
21
|
+
_handleChange(e) {
|
22
|
+
const name = e.target.value;
|
23
|
+
this.props._updateName(name);
|
24
|
+
}
|
25
|
+
|
26
|
+
render() {
|
27
|
+
return (
|
28
|
+
<div>
|
29
|
+
<h3>
|
30
|
+
Hello, {this.props.name}!
|
31
|
+
</h3>
|
32
|
+
<p>
|
33
|
+
Say hello to:
|
34
|
+
<input type="text" ref="name" value={this.props.name} onChange={this._handleChange} />
|
35
|
+
</p>
|
36
|
+
</div>
|
37
|
+
);
|
38
|
+
}
|
39
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import React, { PropTypes } from 'react';
|
2
|
+
import HelloWorldWidget from '../components/HelloWorldWidget';
|
3
|
+
import _ from 'lodash';
|
4
|
+
|
5
|
+
// Simple example of a React "smart" component
|
6
|
+
export default class HelloWorld extends React.Component {
|
7
|
+
constructor(props, context) {
|
8
|
+
super(props, context);
|
9
|
+
|
10
|
+
// Uses lodash to bind all methods to the context of the object instance, otherwise
|
11
|
+
// the methods defined here would not refer to the component's class, not the component
|
12
|
+
// instance itself.
|
13
|
+
_.bindAll(this, '_updateName');
|
14
|
+
}
|
15
|
+
|
16
|
+
static propTypes = {
|
17
|
+
name: PropTypes.string.isRequired, // this is passed from the Rails view
|
18
|
+
}
|
19
|
+
|
20
|
+
state = {name: this.props.name} // how to set initial state in es2015 class syntax
|
21
|
+
|
22
|
+
_updateName(name) {
|
23
|
+
this.setState({name: name});
|
24
|
+
}
|
25
|
+
|
26
|
+
render() {
|
27
|
+
return (
|
28
|
+
<div>
|
29
|
+
<HelloWorldWidget name={this.state.name} _updateName={this._updateName} />
|
30
|
+
</div>
|
31
|
+
);
|
32
|
+
}
|
33
|
+
}
|