KEMBAR78
Intro to ReactJS | PDF
Intro to ReactJS
!
!
!
Jeff Winkler
@winkler1
http://react.rocks
What I'll be showing
• Current approaches
• React
• Demos
• Summarize
Webdev Landscape in 2015
JQuery!
$('article.left section').click(function() {
var was_selected = $(this).hasClass('section-selected');
$('article.left section').removeClass('section-selected');
if (!was_selected) {
$(this).addClass('section-selected');
}
});
!
$('article.right section').click(function() {
$(this).toggleClass('right-selected');
if ($('section.right-selected')) {
$(this).children('input.choose').toggle();
}
});
Backbone
Ember
Angular
!
• MVC
• Angular Markup: ng-model, ng-show, ng-repeat
• Dirty checking, speed limitations
• Large API.
• Scopes are inherited.
Angular Scope
Angular Scope
Common Problems
Shared Mutable State
Core Problem
• Separation of Concerns
app/partials/button.html
app/css/button.css
app/js/directives/button.js
REACT
Thesis: React is
• Cohesive
!
• Easy to reason about
Quick History
• Apr 2012: Instagram purchase.
• June 2013 Open-sourced
Users
AirBNB, BBC, CodeAcademy, Dropbox, Facebook,
Flipboard, Github, Imgur, Instagram, Khan
Academy, Netflix, NYT, PayPal, Reddit, Redfin,
Uber, Wired, Yahoo…
Give it 5 Minutes
Simple Component
var HelloMessage = React.createClass({!
render: function() {!
return <div>Hello {this.props.name}</div>;!
}!
});!
!
React.render(<HelloMessage name="John" />,
mountNode);
JSX
var HelloMessage = React.createClass({!
render: function() {!
return <div>Hello {this.props.name}</div>;!
}!
});!
!
React.render(<HelloMessage name="John" />,
mountNode);
Templating languages have a cost: they make building user
interfaces harder. Doing something simple like alternating row
colors in a table requires jumping through hoops in many languages.
!
What we should do instead is accept that user interfaces are becoming
more and more complicated and that we need a real programming
language (with all of its expressive power) to build user interfaces at
scale.
!
(With React) instead of an oversimplified templating language, you
get to use JavaScript to build abstractions and reuse code.
— Pete Hunt
JSX
var HelloMessage = React.createClass({!
render: function() {!
return <div>Hello {this.props.name}</div>;!
}!
});!
!
React.render(<HelloMessage name="John" />,
mountNode);
JSX -> createElement
var HelloMessage = React.createClass({displayName:
"HelloMessage",!
render: function() {!
return React.createElement("div", null, "Hello ",
this.props.name);!
}!
});!
!
React.render(React.createElement(HelloMessage, {name:
"John"}), mountNode);
f(data)=virtual DOM
var HelloMessage = React.createClass({!
render: function() {!
return <div>Hello {this.props.name}</div>;!
}!
});!
!
React.render(<HelloMessage name="John" />,
mountNode);
Using a Component
var HelloMessage = React.createClass({!
render: function() {!
return <div>Hello {this.props.name}</div>;!
}!
});!
!
React.render(<HelloMessage name="John" />,
mountNode);
Passing props
var HelloMessage = React.createClass({!
render: function() {!
return <div>Hello {this.props.name}</div>;!
}!
});!
!
React.render(<HelloMessage name="John" />,
mountNode);
Questions?
var HelloMessage = React.createClass({!
render: function() {!
return <div>Hello {this.props.name}</div>;!
}!
});!
!
React.render(<HelloMessage name="John" />,
mountNode);
State
Timer: has secondsElapsed
var Timer = React.createClass({!
getInitialState() {!
return {secondsElapsed: 0};!
},!
componentDidMount: function() {!
this.interval = setInterval(this.tick, 1000);!
},!
tick() {!
this.setState({secondsElapsed: this.state.secondsElapsed + 1});!
},!
render() {!
return (!
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>!
);!
}!
});
Initialize State
var Timer = React.createClass({!
getInitialState() {!
return {secondsElapsed: 0};!
},!
componentDidMount: function() {!
this.interval = setInterval(this.tick, 1000);!
},!
tick() {!
this.setState({secondsElapsed: this.state.secondsElapsed + 1});!
},!
render() {!
return (!
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>!
);!
}!
});
setState()
var Timer = React.createClass({!
getInitialState() {!
return {secondsElapsed: 0};!
},!
componentDidMount: function() {!
this.interval = setInterval(this.tick, 1000);!
},!
tick() {!
this.setState({secondsElapsed: this.state.secondsElapsed + 1});!
},!
render() {!
return (!
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>!
);!
}!
});
render
var Timer = React.createClass({!
getInitialState() {!
return {secondsElapsed: 0};!
},!
componentDidMount: function() {!
this.interval = setInterval(this.tick, 1000);!
},!
tick() {!
this.setState({secondsElapsed: this.state.secondsElapsed + 1});!
},!
render() {!
return (!
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>!
);!
}!
});
Components -> App
Composition
var PictureOfTheDay = require('./Components/PictureOfTheDay.js');!
var DateBrowser = require('./Components/DateBrowser.js');!
var Title = require('./Components/Title.js');!
!
var SpacePics = React.createClass ({!
render() {!
return (!
<div>!
<Title title={this.state.title} />!
<PictureOfTheDay picture={this.state.picture} />!
<DateBrowser date={this.state.date} onChange={this._onDateChange} />!
</div>!
);!
require()
var PictureOfTheDay = require('./Components/PictureOfTheDay.js');!
var DateBrowser = require('./Components/DateBrowser.js');!
var Title = require('./Components/Title.js');!
!
var SpacePics = React.createClass ({!
render() {!
return (!
<div>!
<Title title={this.state.title} />!
<PictureOfTheDay picture={this.state.picture} />!
<DateBrowser date={this.state.date} onChange={this._onDateChange} />!
</div>!
);!
Passing data to children
var PictureOfTheDay = require('./Components/PictureOfTheDay.js');!
var DateBrowser = require('./Components/DateBrowser.js');!
var Title = require('./Components/Title.js');!
!
var SpacePics = React.createClass ({!
render() {!
return (!
<div>!
<Title title={this.state.title} />!
<PictureOfTheDay picture={this.state.picture} />!
<DateBrowser date={this.state.date} onChange={this._onDateChange} />!
</div>!
);!
Data from parent to child
Need-to-know
var PictureOfTheDay = require('./Components/PictureOfTheDay.js');!
var DateBrowser = require('./Components/DateBrowser.js');!
var Title = require('./Components/Title.js');!
!
var SpacePics = React.createClass ({!
render() {!
return (!
<div>!
<Title title={this.state.title} />!
<PictureOfTheDay picture={this.state.picture} />!
<DateBrowser date={this.state.date} onChange={this._onDateChange} />!
</div>!
);!
Questions?
Demos
Virtual DOM!
Creating a component
ReactNative
Demo #1: Virtual DOM
Virtual DOM Demo:
TODOMVC
DOMListener
Our script
• Create new: Apples, Bread
• Check off Apples
• Switch between tabs
Angular
Angular
React
Demos
Virtual DOM
Creating a component!
ReactNative
Demo #2: Encapsulation
• Internal state
• UI actions
• refactoring
Hello World
• import React from 'react';



export default class WhosAsleepScore
extends React.Component {

render() {

return (

<h1>Hello, world!</h1>

);

}

}
Change->Hot Reload
state: {count:0}
code
• import React from 'react';



export default class WhosAsleepScore extends
React.Component {

constructor(props) {

super(props);

this.state={count:0};

}

render() {

let {count}= this.state;

return (

<h1>Who's Asleep score: {count}</h1>

);

}

}
Count the sleepers!
Change Request
!
!
!
!
!
Change display
End Result
import React from 'react';

export default class WhosAsleepScore extends React.Component {

constructor(props) {

super(props);

this.state = {count: 0};

}

addSleeper() {

this.setState({count:this.state.count+1});

}



render() {

return (

<div>

<img src='ct.png' onClick={this.addSleeper.bind(this)} />

<span style={countStyle}>{this.state.count}</span>

</div>

);

}

}
Demos
Virtual DOM
Creating a component!
ReactNative
Demo #3: ReactNative
react-native-spacepics
Demo- Overview
Components
Demo-Changing Code
// if we have an error

if (this.state.error !== null) {

innerNode = <ErrorWidget title="NASA
API Error" message={this.state.error} />;

title = 'Error';

}
If Error
ErrorWidget
• var React = require('react-native');

var {

StyleSheet,

Text,

View,

} = React;



class ErrorWidget extends React.Component {

render() {

return (

<View style={styles.container}>

<Text style={styles.title}>{this.props.title}</Text>

<Text style={styles.message}>{this.props.message}</
Text>

</View>

);

}

}
propTypes
class ErrorWidget extends React.Component {!
propTypes: {!
message: React.PropTypes.string.isRequired,!
title: React.PropTypes.string.isRequired,!
},

render() {

return (

<View style={styles.container}>

<Text style={styles.title}>{this.props.title}</Text>

<Text style={styles.message}>{this.props.message}</Text>

</View>

);

}

}
Loading
// if we don't have a picture

else if (this.state.picture === null) {

innerNode = <Loading title="Getting
Image..." />;

title = 'Loading...';

}!
Loading Widget
• var React = require('react-native');

var {

StyleSheet,

ActivityIndicatorIOS,

Text,

View,

} = React;



class Loading extends React.Component {

render() {

return (

<View style={styles.container}>

<ActivityIndicatorIOS animating={true} />

<Text style={styles.title}>{this.props.title}</Text>

</View>

);

}

}
else: Picture
// if we have a picture

else {

innerNode = <PictureOfTheDay
picture={this.state.picture} />;

title = this.state.picture.title;

}!
Components
Demos
Virtual DOM
Creating a component
ReactNative
Zooming Out
Encapsulation
Composition
SpacePics
PictureOfTheDay
Image
Time
Summary
React is easy to reason about
Where to go from here?
• http://facebook.github.io/react/
• search “Thinking in React”
!
THANK YOU
!
!
Jeff Winkler
@winkler1
http://react.rocks
Reaction to JSX

Intro to ReactJS

  • 1.
    Intro to ReactJS ! ! ! JeffWinkler @winkler1 http://react.rocks
  • 3.
    What I'll beshowing • Current approaches • React • Demos • Summarize
  • 4.
  • 5.
    JQuery! $('article.left section').click(function() { varwas_selected = $(this).hasClass('section-selected'); $('article.left section').removeClass('section-selected'); if (!was_selected) { $(this).addClass('section-selected'); } }); ! $('article.right section').click(function() { $(this).toggleClass('right-selected'); if ($('section.right-selected')) { $(this).children('input.choose').toggle(); } });
  • 6.
  • 7.
  • 8.
    Angular ! • MVC • AngularMarkup: ng-model, ng-show, ng-repeat • Dirty checking, speed limitations • Large API. • Scopes are inherited.
  • 9.
  • 10.
  • 11.
  • 14.
  • 15.
    Core Problem • Separationof Concerns app/partials/button.html app/css/button.css app/js/directives/button.js
  • 16.
  • 17.
    Thesis: React is •Cohesive ! • Easy to reason about
  • 18.
    Quick History • Apr2012: Instagram purchase. • June 2013 Open-sourced
  • 19.
    Users AirBNB, BBC, CodeAcademy,Dropbox, Facebook, Flipboard, Github, Imgur, Instagram, Khan Academy, Netflix, NYT, PayPal, Reddit, Redfin, Uber, Wired, Yahoo…
  • 20.
    Give it 5Minutes
  • 21.
    Simple Component var HelloMessage= React.createClass({! render: function() {! return <div>Hello {this.props.name}</div>;! }! });! ! React.render(<HelloMessage name="John" />, mountNode);
  • 22.
    JSX var HelloMessage =React.createClass({! render: function() {! return <div>Hello {this.props.name}</div>;! }! });! ! React.render(<HelloMessage name="John" />, mountNode);
  • 24.
    Templating languages havea cost: they make building user interfaces harder. Doing something simple like alternating row colors in a table requires jumping through hoops in many languages. ! What we should do instead is accept that user interfaces are becoming more and more complicated and that we need a real programming language (with all of its expressive power) to build user interfaces at scale. ! (With React) instead of an oversimplified templating language, you get to use JavaScript to build abstractions and reuse code. — Pete Hunt
  • 25.
    JSX var HelloMessage =React.createClass({! render: function() {! return <div>Hello {this.props.name}</div>;! }! });! ! React.render(<HelloMessage name="John" />, mountNode);
  • 26.
    JSX -> createElement varHelloMessage = React.createClass({displayName: "HelloMessage",! render: function() {! return React.createElement("div", null, "Hello ", this.props.name);! }! });! ! React.render(React.createElement(HelloMessage, {name: "John"}), mountNode);
  • 27.
    f(data)=virtual DOM var HelloMessage= React.createClass({! render: function() {! return <div>Hello {this.props.name}</div>;! }! });! ! React.render(<HelloMessage name="John" />, mountNode);
  • 28.
    Using a Component varHelloMessage = React.createClass({! render: function() {! return <div>Hello {this.props.name}</div>;! }! });! ! React.render(<HelloMessage name="John" />, mountNode);
  • 29.
    Passing props var HelloMessage= React.createClass({! render: function() {! return <div>Hello {this.props.name}</div>;! }! });! ! React.render(<HelloMessage name="John" />, mountNode);
  • 30.
    Questions? var HelloMessage =React.createClass({! render: function() {! return <div>Hello {this.props.name}</div>;! }! });! ! React.render(<HelloMessage name="John" />, mountNode);
  • 31.
  • 32.
    Timer: has secondsElapsed varTimer = React.createClass({! getInitialState() {! return {secondsElapsed: 0};! },! componentDidMount: function() {! this.interval = setInterval(this.tick, 1000);! },! tick() {! this.setState({secondsElapsed: this.state.secondsElapsed + 1});! },! render() {! return (! <div>Seconds Elapsed: {this.state.secondsElapsed}</div>! );! }! });
  • 33.
    Initialize State var Timer= React.createClass({! getInitialState() {! return {secondsElapsed: 0};! },! componentDidMount: function() {! this.interval = setInterval(this.tick, 1000);! },! tick() {! this.setState({secondsElapsed: this.state.secondsElapsed + 1});! },! render() {! return (! <div>Seconds Elapsed: {this.state.secondsElapsed}</div>! );! }! });
  • 34.
    setState() var Timer =React.createClass({! getInitialState() {! return {secondsElapsed: 0};! },! componentDidMount: function() {! this.interval = setInterval(this.tick, 1000);! },! tick() {! this.setState({secondsElapsed: this.state.secondsElapsed + 1});! },! render() {! return (! <div>Seconds Elapsed: {this.state.secondsElapsed}</div>! );! }! });
  • 35.
    render var Timer =React.createClass({! getInitialState() {! return {secondsElapsed: 0};! },! componentDidMount: function() {! this.interval = setInterval(this.tick, 1000);! },! tick() {! this.setState({secondsElapsed: this.state.secondsElapsed + 1});! },! render() {! return (! <div>Seconds Elapsed: {this.state.secondsElapsed}</div>! );! }! });
  • 36.
  • 37.
    Composition var PictureOfTheDay =require('./Components/PictureOfTheDay.js');! var DateBrowser = require('./Components/DateBrowser.js');! var Title = require('./Components/Title.js');! ! var SpacePics = React.createClass ({! render() {! return (! <div>! <Title title={this.state.title} />! <PictureOfTheDay picture={this.state.picture} />! <DateBrowser date={this.state.date} onChange={this._onDateChange} />! </div>! );!
  • 38.
    require() var PictureOfTheDay =require('./Components/PictureOfTheDay.js');! var DateBrowser = require('./Components/DateBrowser.js');! var Title = require('./Components/Title.js');! ! var SpacePics = React.createClass ({! render() {! return (! <div>! <Title title={this.state.title} />! <PictureOfTheDay picture={this.state.picture} />! <DateBrowser date={this.state.date} onChange={this._onDateChange} />! </div>! );!
  • 39.
    Passing data tochildren var PictureOfTheDay = require('./Components/PictureOfTheDay.js');! var DateBrowser = require('./Components/DateBrowser.js');! var Title = require('./Components/Title.js');! ! var SpacePics = React.createClass ({! render() {! return (! <div>! <Title title={this.state.title} />! <PictureOfTheDay picture={this.state.picture} />! <DateBrowser date={this.state.date} onChange={this._onDateChange} />! </div>! );!
  • 40.
  • 42.
    Need-to-know var PictureOfTheDay =require('./Components/PictureOfTheDay.js');! var DateBrowser = require('./Components/DateBrowser.js');! var Title = require('./Components/Title.js');! ! var SpacePics = React.createClass ({! render() {! return (! <div>! <Title title={this.state.title} />! <PictureOfTheDay picture={this.state.picture} />! <DateBrowser date={this.state.date} onChange={this._onDateChange} />! </div>! );!
  • 43.
  • 44.
    Demos Virtual DOM! Creating acomponent ReactNative
  • 45.
  • 46.
  • 47.
  • 48.
    Our script • Createnew: Apples, Bread • Check off Apples • Switch between tabs
  • 49.
  • 50.
  • 51.
  • 53.
    Demos Virtual DOM Creating acomponent! ReactNative
  • 54.
    Demo #2: Encapsulation •Internal state • UI actions • refactoring
  • 60.
    Hello World • importReact from 'react';
 
 export default class WhosAsleepScore extends React.Component {
 render() {
 return (
 <h1>Hello, world!</h1>
 );
 }
 }
  • 61.
  • 62.
  • 63.
    code • import Reactfrom 'react';
 
 export default class WhosAsleepScore extends React.Component {
 constructor(props) {
 super(props);
 this.state={count:0};
 }
 render() {
 let {count}= this.state;
 return (
 <h1>Who's Asleep score: {count}</h1>
 );
 }
 }
  • 64.
  • 65.
  • 66.
  • 67.
    End Result import Reactfrom 'react';
 export default class WhosAsleepScore extends React.Component {
 constructor(props) {
 super(props);
 this.state = {count: 0};
 }
 addSleeper() {
 this.setState({count:this.state.count+1});
 }
 
 render() {
 return (
 <div>
 <img src='ct.png' onClick={this.addSleeper.bind(this)} />
 <span style={countStyle}>{this.state.count}</span>
 </div>
 );
 }
 }
  • 68.
    Demos Virtual DOM Creating acomponent! ReactNative
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 75.
    // if wehave an error
 if (this.state.error !== null) {
 innerNode = <ErrorWidget title="NASA API Error" message={this.state.error} />;
 title = 'Error';
 } If Error
  • 76.
    ErrorWidget • var React= require('react-native');
 var {
 StyleSheet,
 Text,
 View,
 } = React;
 
 class ErrorWidget extends React.Component {
 render() {
 return (
 <View style={styles.container}>
 <Text style={styles.title}>{this.props.title}</Text>
 <Text style={styles.message}>{this.props.message}</ Text>
 </View>
 );
 }
 }
  • 78.
    propTypes class ErrorWidget extendsReact.Component {! propTypes: {! message: React.PropTypes.string.isRequired,! title: React.PropTypes.string.isRequired,! },
 render() {
 return (
 <View style={styles.container}>
 <Text style={styles.title}>{this.props.title}</Text>
 <Text style={styles.message}>{this.props.message}</Text>
 </View>
 );
 }
 }
  • 79.
    Loading // if wedon't have a picture
 else if (this.state.picture === null) {
 innerNode = <Loading title="Getting Image..." />;
 title = 'Loading...';
 }!
  • 80.
    Loading Widget • varReact = require('react-native');
 var {
 StyleSheet,
 ActivityIndicatorIOS,
 Text,
 View,
 } = React;
 
 class Loading extends React.Component {
 render() {
 return (
 <View style={styles.container}>
 <ActivityIndicatorIOS animating={true} />
 <Text style={styles.title}>{this.props.title}</Text>
 </View>
 );
 }
 }
  • 81.
    else: Picture // ifwe have a picture
 else {
 innerNode = <PictureOfTheDay picture={this.state.picture} />;
 title = this.state.picture.title;
 }!
  • 82.
  • 85.
    Demos Virtual DOM Creating acomponent ReactNative
  • 86.
  • 87.
  • 88.
  • 89.
  • 91.
    Summary React is easyto reason about
  • 93.
    Where to gofrom here? • http://facebook.github.io/react/ • search “Thinking in React” !
  • 94.
  • 95.