70
REACT.JS: BEYOND THE BROWSER REACT.JS: BEYOND THE BROWSER REACT.JS: BEYOND THE BROWSER REACT.JS: BEYOND THE BROWSER REACT.JS: BEYOND THE BROWSER REACT.JS: BEYOND THE BROWSER REACT.JS: BEYOND THE BROWSER REACT.JS: BEYOND THE BROWSER REACT.JS: BEYOND THE BROWSER REACT.JS: BEYOND THE BROWSER REACT.JS: BEYOND THE BROWSER REACT.JS: BEYON THE BROWSER REACT.JS: BEYON THE BROWSER REACT.JS: BEYON THE BROWSER REACT.JS: BEYON THE BROWSER REACT.JS: BEYON THE BROWSER REACT.JS: BEYON THE BROWSER REACT.JS: BEYON THE BROWSER REACT.JS: BEYON THE BROWSER REACT.JS: BEYO THE BROWSER REACT.JS: BEYO THE BROWSER REACT.JS: BEYO REACT.JS: BEYO REACT.JS: BEYO REACT.JS: BEYO REACT.JS: BEYO REACT.JS: BEY REACT.JS: BEYOND THE BROWSER @gabescholz

React.js: Beyond the Browser

  • Upload
    garbles

  • View
    286

  • Download
    0

Embed Size (px)

Citation preview

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND THE BROWSER

REACT.JS: BEYOND REACT.JS: BEYOND REACT.JS: BEYOND REACT.JS: BEYOND REACT.JS: BEYOND

REACT.JS: BEYOND THE BROWSER

@gabescholz

“just remember I am going after you” - Godfrey Chan, wannabe Thought Leader

“the whole reason I am doing the talk is to go after you”

JAVASCRIPT

“… the latest and greatest JavaScript framework comes around every sixteen minutes.” - Allen Pike, King of VanJS

http://www.allenpike.com/2015/javascript-framework-fatigue/

“Helping you select an MV* framework”

!

(with 64 different choices!!)

http://todomvc.com/

CHOICE PARALYSIS /noun/ !

!

the state of being unable to select a proper JavaScript framework !

“I literally can’t feel my legs due to this choice paralysis.”

http://www.sitepoint.com/drowning-in-tools-web-development-industry/

“… people come from a wide variety of backgrounds, and have a wide variety of goals. This constant inflow of new ideas and interests has made the JavaScript community unusually diverse.”

http://www.allenpike.com/2015/javascript-framework-fatigue/

FOAM“FOAM is a full-stack, reactive, deeply MVC metaprogramming

Javascript framework.”<meta name=“description” … />

@gabescholz

e

2. “Learn once, Write anywhere”

1. Why React?

😍 Everything is JavaScript

<!-- template.html --> !<weather-widget forecast=“forecast”> <weather-link href=“http://weather.ca”> sherr, bud </weather-link> </weather-widget>

// component.js !<WeatherWidget forecast={forecast}> <WeatherLink href=“http://weather.ca”> sherr, bud </WeatherLink> </WeatherWidget>

// component.js !React.createElement(WeatherWidget, { forecast: forecast }, React.createElement(WeatherLink, { href: “http://weather.ca” }, “sherr, bud” ) )

Dat JSX, tho

// component.js !React.createElement(“div”, {}, React.createElement(“a”, { href: “http://weather.ca” }, “sherr, bud” ) )

Dat JSX, tho

FEELS GOOD MAN

var WeatherApp = React.createClass({ getInitialState () { return { forecast: ‘sunny’ }; }, render () { var forecast = this.state.forecast; ! return ( <WeatherWidget forecast={forecast}> <WeatherLink href=“http://weather.ca”> sherr, bud </WeatherLink> </WeatherWidget> ) } });

😁 Virtual DOM +

Diffing

renderA: <div /> renderB: <span />

[removeNode <div />], [insertNode <span />]

renderA: <PuttyPatrol /> renderB: <Goldar />

[removeNode <PuttyPatrol />], [insertNode <Goldar />]

renderA: <div id="ahHhhhHh" /> renderB: <div id=“after-10000-years-im-free” />

[replaceAttribute id "after-10000-years-im-free"]

😁 One-way Reactive Rendering

STATE vs PROPS in TWO MINUTES

var Parent = React.createClass({ // ... render () { return ( <div> <Son name={this.state.sonsName} /> <Daughter name={this.state.daughtersName} /> </div> ); } }); !var Daughter = React.createClass({ // ... render () { return ( <div> <div>{this.props.name}</div> <div>{this.state.favouriteColor}</div> <Dog name=`Mini ${this.props.name}` /> </div> ); } });

var Parent = React.createClass({ // … ! updateToLaquesha () { this.setState({ daughtersName: “Laquesha” }); }, ! render () { return ( <div> <button onClick={this.updateToLaquesha} /> <Son name={this.state.sonsName} /> <Daughter name={this.state.daughtersName} /> </div> ); } });

Going beyond the DOM

React Canvas

Created by Flipboard

60 fps on mobile browsers

Last commit ~1 week after React Native released publicly

<Surface> <Layer> <Text style={{ fontFace: ‘Calibri’, fontSize: ‘40pt’ }}>{this.state.text}</Text> </Layer> </Surface>

`

var context = canvas.getContext(‘2d’); context.font = '40pt Calibri'; context.fillText(text, 0, 0);

React Native

Created by Facebook

All of your business logic is written and runs in JavaScript using JavaScriptCore on iOS

UI Kit instead of DOM Nodes

<div> <img src=“http://i.imgur.com/OBB7tLg.gif” /> <input type=“text” /> <span>sherrr, bud</span> </div>

<View> <Image source={{uri: “http://i.imgur.com/OBB7tLg.gif”}} /> <TextInput /> <Text>sherrr, bud</Text> </View>

React Native

*style required but not included

ReactGibbon

Created by Netflix

Runs on their Gibbon platform

Renders JSON instead of DOM

`

I SHOULD PUT REACT ON SOMETHINGI SHOULD PUT REACT ON SOMETHING

https://github.com/garbles/react-pebble-demo

var card = UI.Card({ title: “Fetching movies list”, subtitle: “Just a minute..”, body: “1 sec..” }); card.show(); // ... card.hide(); !!!!!!!<Card title=“Fetching movies list” subtitle=“Just a minute..” body=“1 sec..” />

var list = UI.List(); list.sections([{}]); // for every item var items = list.items(0); list.items(0, items.concat(item)); !list.show(); // ... list.hide(); !!!!!<List onSelect={this.handleSelect}> <Item title=“..” ... /> <Item title=“..” ... /> <Item title=“..” ... /> <Item title=“..” ... /> </List>

var App = React.createClass({ getInitialState () { }, selectItem (item) { }, ! componentDidMount () { ajax(apiUrl, (response) => { this.setState({ movies: response[1].movies }) }); }, ! render () { var movies = this.state.movies.map( movie => { return (<Item title={movie.title} data={movie} />); }); ! if (movies.length) { return <List onSelect={this.selectItem}>{movies}</List>; } else { return <Card ... />; } } });

var App = React.createClass({ getInitialState () { return { movies: [] } }, selectItem (item) { }, ! componentDidMount () { ajax(apiUrl, (response) => { this.setState({ movies: response[1].movies }) }); }, ! render () { var movies = this.state.movies.map( movie => { return (<Item title={movie.title} data={movie} />); }); ! if (movies.length) { return <List onSelect={this.selectItem}>{movies}</List>; } else { return <Card ... />; } } });

var App = React.createClass({ getInitialState () { }, selectItem (item) { }, ! componentDidMount () { ajax(apiUrl, (response) => { this.setState({ movies: response[1].movies }) }); }, ! render () { var movies = this.state.movies.map( movie => { return (<Item title={movie.title} data={movie} />); }); ! if (movies.length) { return <List onSelect={this.selectItem}>{movies}</List>; } else { return <Card ... />; } } });

var App = React.createClass({ getInitialState () { }, selectItem (item) { }, ! componentDidMount () { ajax(apiUrl, (response) => { this.setState({ movies: response[1].movies }) }); }, ! render () { var movies = this.state.movies.map( movie => { return (<Item title={movie.title} data={movie} />); }); ! if (movies.length) { return <List onSelect={this.selectItem}>{movies}</List>; } else { return <Card ... />; } } });

😛 Becoming a React trickster

function createComponent(name) { ! var CustomComponent = function(props) { this.node = new PebbleNode(); this.subscriptions = null; this.listeners = null; this._mountImage = null; this._renderedChildren = null; }; ! CustomComponent.displayName = name; ! for (var i = 1, l = arguments.length; i < l; i++) { assign(CustomComponent.prototype, arguments[i]); } ! return CustomComponent; }

function createComponent(name) { ! var CustomComponent = function(props) { this.node = new PebbleNode(); this.subscriptions = null; this.listeners = null; this._mountImage = null; this._renderedChildren = null; }; ! CustomComponent.displayName = name; ! for (var i = 1, l = arguments.length; i < l; i++) { assign(CustomComponent.prototype, arguments[i]); } ! return CustomComponent; }

function createComponent(name) { ! var CustomComponent = function(props) { this.node = new PebbleNode(); this.subscriptions = null; this.listeners = null; this._mountImage = null; this._renderedChildren = null; }; ! CustomComponent.displayName = name; ! for (var i = 1, l = arguments.length; i < l; i++) { assign(CustomComponent.prototype, arguments[i]); } ! return CustomComponent; }

var Card = createComponent( ‘Card’, NodeMixin, ComponentMixin, ..., { /* additional behaviours */ } ); !var PebbleApp = React.createClass({ render () { return ( <Card title=“Hello World!”/> ); } }); !renderPebble(<PebbleApp />);

var NodeMixin = { putEventListener (...) { /* ... */ }, handleEvent (...) { /* ... */ }, destroyEventListeners (...) { /* ... */ }, applyNodeProps (...) { /* ... */ } }; !var ContainerMixin = assign({}, ReactMultiChild.Mixin, { moveChild (...) { /* ... */ }, createChild (...) { /* ... */ }, replaceChild (...) { /* ... */ }, updateChildrenAtRoot (...) { /* ... */ }, mountAndInjectChildren (...) { /* ... */ } }); !// per component { construct (...) { /* ... */ }, mountComponent (...) { /* ... */ }, unmountComponent (...) { /* ... */ }, receiveComponent (...) { /* ... */ } };

var Card = createComponent(‘Card’, NodeMixin, { construct (element) { this._currentElement = element; this.__instance = new UI.Card(); }, mountComponent (rootID, transaction, context) { var props = this._currentElement.props; this._rootNodeID = rootID; ! this.__instance.prop(props); this.__instance.show(); ! return this.node; }, unmountComponent () { this.__instance.hide(); }, receiveComponent (element) { this._currentElement = element; this.__instance.prop(element.props); } });

var Card = createComponent(‘Card’, NodeMixin, { construct (element) { this._currentElement = element; this.__instance = new UI.Card(); }, mountComponent (rootID, transaction, context) { var props = this._currentElement.props; this._rootNodeID = rootID; ! this.__instance.prop(props); this.__instance.show(); ! return this.node; }, unmountComponent () { this.__instance.hide(); }, receiveComponent (element) { this._currentElement = element; this.__instance.prop(element.props); } });

var Card = createComponent(‘Card’, NodeMixin, { construct (element) { this._currentElement = element; this.__instance = new UI.Card(); }, mountComponent (rootID, transaction, context) { var props = this._currentElement.props; this._rootNodeID = rootID; ! this.__instance.prop(props); this.__instance.show(); ! return this.node; }, unmountComponent () { this.__instance.hide(); }, receiveComponent (element) { this._currentElement = element; this.__instance.prop(element.props); } });

var Card = createComponent(‘Card’, NodeMixin, { construct (element) { this._currentElement = element; this.__instance = new UI.Card(); }, mountComponent (rootID, transaction, context) { var props = this._currentElement.props; this._rootNodeID = rootID; ! this.__instance.prop(props); this.__instance.show(); ! return this.node; }, unmountComponent () { this.__instance.hide(); }, receiveComponent (element) { this._currentElement = element; this.__instance.prop(element.props); } });

var Card = createComponent(‘Card’, NodeMixin, { construct (element) { this._currentElement = element; this.__instance = new UI.Card(); }, mountComponent (rootID, transaction, context) { var props = this._currentElement.props; this._rootNodeID = rootID; ! this.__instance.prop(props); this.__instance.show(); ! return this.node; }, unmountComponent () { this.__instance.hide(); }, receiveComponent (element) { this._currentElement = element; this.__instance.prop(element.props); } });

Resources: !https://docs.google.com/presentation/d/1afMLTCpRxhJpurQ97VBHCZkLbR1TEsRnd3yyxuSQ5YY/edit#slide=id.g380053cce_179 !https://fivejs.codeschool.com/episodes/72-episode-65-march-5th-2015/stories/463-framework-fatigue !http://www.sitepoint.com/drowning-in-tools-web-development-industry/ !http://www.allenpike.com/2015/javascript-framework-fatigue/ !http://www.todomvc.com !Prior Art: !https://github.com/reactjs/react-art !https://github.com/Flipboard/react-canvas !https://github.com/facebook/react !https://github.com/facebook/react-native

THANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKSTHANKS