React on Rails
Vipul A M
@vipulnsward
😓
Â
http://rubyconfindia.org/
Â
http://www.gardencityruby.org/
Â
http://www.deccanrubyconf.org/
Part 1-React
Build UI
V in MVC
Simple
Virtual DOM
Components
Props/State
Re-Render 💥
JSX
// Using JSX to express UI components.
var dropdown =
<Dropdown>
A dropdown list
<Menu>
<MenuItem>Do Something</MenuItem>
<MenuItem>Do Something Fun!</MenuItem>
<MenuItem>Do Something Else</MenuItem>
</Menu>
</Dropdown>;
render(dropdown);
var App = React.createClass({
getInitialState: function() {
return {name: 'Vipul'};
},
render: function() {
console.log(this.props)
return <h1>{this.state.name}</h1>
}
});
React.render(<App name='Vipul'/>, document.body);
Life-Cycle
console.log('Start')
var App = React.createClass({
componentWillMount: function(){
console.log('componentWillMount');
},
componentDidMount: function(){
console.log('componentDidMount');
},
getInitialState: function(){
return { status: true}
},
getDefaultProps: function(){
return {name: 'John'};
},
componentWillReceiveProps: function(nextProps){
console.log('componentWillReceiveProps');
},
shouldComponentUpdate: function(nextProps, nextState){
console.log('shouldComponentUpdate');
return true;
},
componentWillUpdate: function(){
console.log('componentWillUpdate');
},
render: function() {
console.log('render');
return <h1 onClick={this.toggleState}>
{this.state.status.toString()}
</h1>
},
componentWillUnmount: function(){
console.log('componentWillUnmount')
},
toggleState: function() {
this.setState({status: !this.state.status})
}
});
...
shouldComponentUpdate: function(nextProps, nextState){
console.log('shouldComponentUpdate');
return true;
},
componentWillUpdate: function(){
console.log('componentWillUpdate');
},
render: function() {
console.log('render');
return <h1 onClick={this.toggleState}>
{this.state.status.toString()}
</h1>
},
componentWillUnmount: function(){
console.log('componentWillUnmount')
},
toggleState: function() {
this.setState({status: !this.state.status})
}
});
Multiple Components
var FruitsList = React.createClass({
render: function () {
return <div>
<h1>{this.props.name}</h1>
<ul>
<li>Apple</li>
<li>Orange</li>
<li>Banana</li>
</ul>
</div>
}
});
var App = React.createClass({
render: function () {
return <div>
<FruitsList name='Fruits'/>
</div>
}
});
React.render(<App/>, document.body);
Events and forms
...
<form onSubmit={::this.submitPost}>
<div className="form-group">
<textarea className="form-control"
placeholder="Title"
value={this.state.title}
onChange={(event) => this.handleChange(event, 'title')}/>
</div>
...
<div className="form-group">
<button type="submit"
ref="submit"
className="btn btn-success">
Submit
</button>
</div>
</form>
...
handleChange(event, attribute) {
var newState = this.state;
newState[attribute] = event.target.value;
newState.errors = null;
this.setState(newState);
console.log(this.state);
}
...
Part 2-React-Rails
+
=
// Gemfile
gem 'react-rails', '~> 1.0'
// Install
rails g react:install
// Inside application.js
//= require react
//= require react_ujs
//= require components
rails generate react:component Post title:string
body:string
published:bool
published_by:instanceOf{Person}
var Post = React.createClass({
propTypes: {
title: React.PropTypes.string,
body: React.PropTypes.string,
published: React.PropTypes.bool,
publishedBy: React.PropTypes.instanceOf(Person)
},
render: function() {
return (
<div>
<div>Title: {this.props.title}</div>
<div>Body: {this.props.body}</div>
<div>Published: {this.props.published}</div>
<div>Published By: {this.props.publishedBy}</div>
</div>
);
}
});
<%= react_component('HelloMessage', {name: 'John'}, {prerender: true}) %>
<!-- becomes: -->
<div data-react-class="HelloMessage"
data-react-props="{"name":"John"}">
<h1>Hello, John!</h1>
</div>
// From ActiveRecord
<%= react_component('Posts', posts: @posts) %>
Text
// variables
const a=10; let b = 10;
//arrow functions
odds = evens.map(v => v +1 )
// Spread Operators
let str = "foo"
let chars = [ ...str ] // [ "f", "o", "o" ]
// String Interpolation
message = `Hello ${customer.name}`
// Classes!
class Shape {
constructor (id, x, y) {
this.id = id
this.move(x, y)
}
move (x, y) {
this.x = x
this.y = y
}
}
Demo
submitPost(event) {
event.preventDefault();
fetch('/posts', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({post: this.state})
}).then(::this.parseJSON)
.then(::this.setPosts)
.catch(function (ex) {
console.log('parsing failed', ex)
});
}
Flux
Redux
gem react_on_rails
webpack
​@vipulnsward
bigbinary.com/videos
https://github.com/shakacode/react_on_rails
https://github.com/vipulnsward/react-rails-browserify
Vipul A M
@vipulnsward
@bigbinary
React on Rails Rubyconf Taiwan 2015
By Vipul Amler
React on Rails Rubyconf Taiwan 2015
React on Rails Rubyconf Taiwan 2015
- 3,724