On Github webbushka / react-stuffs-slides
"React allows you to essentiallycreate a page, of single page apps"— Alexandr Marinenko
and WORST of all
Angular's style of dirty checking has the most unpredictable performance. obscures data flow aka MAGIC!* If you want an object to update another object you have to register watches whenever those are outside of the DOMWhat is it?
"Flux is an application architecture for React"
WTF is reflux?
Currently we either mutate data or do something like
let original = {a:'1', b:2, c:3}; let changed = JSON.parse(JSON.stringify(original)); changed.b = 50; console.log(original.b) // 2 console.log(changed.b) // 50
when we don't want to mutate the data
Allows us to write ES6 and compiles it back to ES5
Let's see what's new!
function scoped:
function() { if (true) { var i = 'hello'; } console.log(i); // hello }
block scoped:
function() { if (true) { const i = 'hello'; let j = 'world'; } console.log(i) // ReferenceError console.log(j) // ReferenceError }
hoisted:
function() { console.log(a); // undefined var a = 'var'; }
not hoisted:
function() { console.log(a); // ReferenceError console.log(b); // ReferenceError let a = 'let'; const b = 'const'; }
const foo; // SyntaxError
const foo = someObject; foo = someOtherObject; // SyntaxError foo.bar = 'hello';
import React from 'react'; import ApiClient from './lib/ApiClient'; class MyComponent extends React.Component { ... } export MyComponent;
// example.js export default function() {...}; // example2.js import ex from './example'; ex();
// example.js export function ex1() {...}; export function ex2() {...}; export function ex3() {...}; // example2.js import {ex2, ex3} from './example.js';
// example.js export function ex1() {...}; export function ex2() {...}; export function ex3() {...}; // example2.js import * as EX from './example.js'; EX.ex1(); EX.ex2();
// component.js import Header from './components/header'; import Button from './components/button'; import Footer from './components/footer'; render() { return ( <Header /> <Button /> <Footer /> ) }
// index.js import Header from './header'; import Button from './button'; import Footer from './footer'; export default { Header, Button, Footer }; // component.js import { Header, Button, Footer } from './components/'; render() { return ( <Header /> <Button /> <Footer /> ) }
export from
// index.js export Header from './header'; export Button from './button'; export Footer from './footer'; // component.js import { Header, Button, Footer } from './components/'; render() { return ( <Header /> <Button /> <Footer /> ) }
function Dog() {...} Dog.prototype = new Animal();
class Dog extends Animal { ... }
'use strict'; import React from 'react'; class EmployeeCount extends React.Component { constructor(props) { super(props); this.state = { company: props.company }; } render() { return ( <div> Active Employees: {this.state.company.employeeCount} </div> ) } } EmployeeCount.propTypes = { company: React.PropTypes.object.isRequired }; EmployeeCount.defaultProps = { company: {} }; export default EmployeeCount;
'use strict'; import React from 'react'; export class EmployeeCount extends React.Component { static propTypes = { company: React.PropTypes.object.isRequired } static defaultProps = { company: {} } constructor(props) { super(props); this.state = { company: props.company }; } render() { return ( <div> Active Employees: {this.state.company.employeeCount} </div> ) } }
'use strict'; const log = console.info.bind(console); class MenuItem { constructor() { this.name = "Menu Item"; } eat() { log(`Eating ${this.name}`); } } class Taco extends MenuItem { constructor() { super(); this.name = 'Taco'; } } class Burrito extends MenuItem { constructor() { super(); this.name = 'Burrito'; } } const items = [new Taco(), new Burrito()] items.forEach(i => i.eat());
'use strict'; var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var log = console.info.bind(console); var MenuItem = (function () { function MenuItem() { _classCallCheck(this, MenuItem); log('Menu item created'); this.name = 'Menu Item'; } _createClass(MenuItem, [{ key: 'eat', value: function eat() { log('Eating ' + this.name); } }]); return MenuItem; })(); var Taco = (function (_MenuItem) { function Taco() { _classCallCheck(this, Taco); _get(Object.getPrototypeOf(Taco.prototype), 'constructor', this).call(this); log('Taco created'); this.name = 'Taco'; } _inherits(Taco, _MenuItem); return Taco; })(MenuItem); var Burrito = (function (_MenuItem2) { function Burrito() { _classCallCheck(this, Burrito); _get(Object.getPrototypeOf(Burrito.prototype), 'constructor', this).call(this); log('Burrito created'); this.name = 'Burrito'; } _inherits(Burrito, _MenuItem2); return Burrito; })(MenuItem); var items = [new Taco(), new Burrito()]; items.forEach(function (i) { return i.eat(); });
the more you inherit the bigger the performance cut ... as with life, be smart with your inheritance
'use strict'; class MenuItem { constructor() { this.name = 'Menu Item'; } eat() { console.info(`Eating ${this.name}`); } } class Taco extends MenuItem { constructor() { super(); this.name = 'Taco'; } } class HardTaco extends Taco { constructor() { super(); this.name = 'Hard Taco'; } } class BeefTaco extends HardTaco { constructor() { super(); this.name = 'Beef Taco'; } } class SpicyTaco extends BeefTaco { constructor() { super(); this.name = 'Spicy Taco'; } } class Burrito extends MenuItem { constructor() { super(); this.name = 'Burrito'; } } let items = [new Taco(), new Burrito(), new SpicyTaco()]; items.forEach(i => i.eat());
const arr = [1, 2, 3]; const x = arr[0]; const y = arr[1]; function(obj) { const value = obj.value; } const name = this.props.name; const dob = this.props.dobs;
const [x, y] = [1, 2, 3]; function({ value }) {} const {name, dob} = this.props;
// Fun const {props: {fontStyle, user}, state: {name}, context: {router}} = this;
// More understandable const {fontStyle, user} = this.props; const {name} = this.state; const {router} = this.context;
updateState(payload) { const name = payload.name || 'stranger'; this.setState({ name: name }); }
updateState({ name = 'stranger'}) { this.setState({name}); }
// Arrays - ES6 const arr = [1, 2, 3]; ...arr; // 1 2 3 // Objects - ESNext const obj = {a: 1, b: 2, c: 3}; ...obj; // {a: 1, b: 2, c: 3} // JSX (supported by default) <MyComponent {...this.props} />
const [x, y] = [1, 2, 3, 4]; x; // 1 y; // 2 const [x, y, ...rest] = [1, 2, 3, 4]; x; // 1 y; // 2 rest; // [3, 4]
const baseStyle = { background: '#b4d455', padding: 10 }; render() { const { altStyle } = this.props; const blendedStyle = { ...baseStyle, ...altStyle }; return <div style={blendedStyle}>Yay!</div>; }
The value of this inside of the function isdetermined by where the arrow function isdefined and not where it is used.— Understanding ECMAScript 6, Nicolas C. Zakas
function(item) { return item.value + 1; }
(item) => { return item.value + 1; }
({value}) => { return value + 1; }
({value}) => value + 1;
Class level syntactic sugar for higher-order functions
'use strict'; import authorized from './decorator/authorized'; import clientWidth from './decorator/clientWidth'; import poll from './decorator/poll'; @authorized @clientWidth @poll class SimpleView extends React.Component { ... } export default SimpleView;
Thanks to James White and Erin HoustonAttribution to Jem Young for his ES6 talk at React Rally