nyc react meetup - jun 2015

23
React meetup, Jun 2015 Tom Rogers - Principal Architect, ADP Innovation Lab

Upload: tomrogers3

Post on 14-Aug-2015

54 views

Category:

Technology


1 download

TRANSCRIPT

React meetup, Jun 2015!Tom Rogers - Principal Architect, ADP Innovation Lab

Overview

• About the Lab!

• Why we use React!

• State management!

• Baobab

About the LabBuilding the next generation of ADP’s products

490 thousand

cloud clients

5 million

logins a day

19.5 thousand

logins a sec

35 million

active users

SaaS

We’re hiring

Developers / Engineers SDETs / QAs

Architects Scrum Masters

Solution Architects

[email protected]

Why we use ReactBecause it’s awesome for what we need

State managementIt’s complicated

Connecting data to UI (and back again)

• Where should data live

• Which component mutates (owns) state

• Decentralized or centralized (e.g. Om, Morearty, Baobab and others)

• Some data flow approaches

• Flux / CQRS / DDD (and which implementation?)

• RelayReferences http://facebook.github.io/react/docs/thinking-in-react.html https://github.com/enaqx/awesome-react#flux-implementations https://github.com/enaqx/awesome-react#relay https://github.com/uberVU/react-guide/blob/master/props-vs-state.md http://jaysoo.ca/2015/02/06/what-the-flux/

Flux overview• Different types of changes

• Initial data load

• User interaction

• Navigation and routing

• Interaction & sync with server

• Dependencies across stores and UI components (minimize & avoid reentrancy)

• Functional Reactive Programming (FRP) (more advanced)References https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

Baobabhttps://github.com/Yomguithereal/baobab

Baobab• Persistent and optionally immutable data tree with cursors

• Centralized model for application state

• Feature highlights

• Cursors, efficient mutations, events, flexible selection and traversal, facets, undo/redo and more

• Can be paired with React easily (baobab-react)

Create a tree and a cursorvar Baobab = require('baobab'); var stateTree = new Baobab({ admin: { users: [] }, home: { news: [] } }); !

var adminCursor = stateTree.select('admin'); var admin = adminCursor.get(); // { users: [] }

Listen to updates (on nested data)var notificationsCursor = adminCursor.select('notifications'); var feedsCursor = stateTree.select('home', 'feeds'); !adminCursor.on('update', function () { console.log('I saw a change'); // I will trigger }); !notificationsCursor.on('update', function () { console.log('I saw a change'); // I will trigger }); !feedsCursor.on('update', function () { console.log('I saw a change'); // Won’t trigger, on a different branch }); !notificationsCursor.push('foo');

Connect cursor(s) to a componentvar stateTree = require('./stateTree.js'); var React = require('react'); !var listCursor = stateTree.select('admin', 'notifications', 'list'); var MyComponent = React.createClass({ mixins: [listCursor.mixin], renderNotification: function (notification) { return ( <li>{notification.title}</li> ); }, render: function () { return ( <ul> {this.state.cursor.map(this.renderNotification)} </ul> ); } });

State changes

var Baobab = require('baobab'); var stateTree = new Baobab({ query: '', onlyProductsInStock: false, products: [] }); !module.exports = stateTree;

var stateTree = require('./stateTree'); var ajax = require('ajax'); module.exports = { showOnlyProductsInStock: function () { stateTree.set('onlyProductsInStock', true); }, showAllProducts: function () { stateTree.set('onlyProductsInStock', false); }, searchProducts: function (query) { stateTree.set('query', query); ajax.get('/products', query) .done(function (products) { stateTree.set('products', products); }); } };

stateTree.js

main.js

Optimizing renderingvar Baobab = require('baobab'); var ReactAddons = require('react/addons'); !

var stateTree = new Baobab({ notifications: [] }, { mixins: [ReactAddons.PureRenderMixin], shiftReferences: true }); !

module.exports = stateTree;

Undo / redovar baobab = new Baobab({colors: ['blue']}, {asynchronous: false}), cursor = baobab.select('colors'); !// Starting to record state, with 10 records maximum cursor.startRecording(10); !cursor.push('yellow'); cursor.push('purple'); cursor.push('orange'); !cursor.get(); >>> ['blue', 'yellow', 'purple', 'orange'] !cursor.undo(); cursor.get(); >>> ['blue', 'yellow', 'purple'] !cursor.undo(2); cursor.get(); >>> ['blue']

React integrationRoot Branchimport React, {Component} from 'react'; import Baobab from 'baobab'; import {root} from 'baobab-react/higher-order'; !var tree = new Baobab({ name: 'John', surname: 'Talbot' }); !class Application extends Component { render() { return ( <div> <OtherComponent /> </div> ); } } !var ComposedComponent = root(Application, tree); !React.render(<ComposedComponent />, mountNode);

import React, {Component} from 'react'; import {branch} from 'baobab-react/higher-order'; !class MyComponent extends Component { render() { ! // Cursor data is passed through props return ( <span> Hello {this.props.name} {this.props.surname} </span> ); } } !export default branch(MyComponent, { cursors: { name: ['name'], surname: ['surname'] } });

We’re hiring

Developers / Engineers SDETs / QAs

Architects Scrum Masters

Solution Architects

[email protected]

Thank you@tomrogers5

[email protected] https://linkedin.com/in/tomrogers3

Resources• https://github.com/tomrogers3/react-webgl-globe-viz

• https://www.youtube.com/watch?v=x7cQ3mrcKaY (highly recommended)

• http://facebook.github.io/react/docs/thinking-in-react.html

• https://github.com/enaqx/awesome-react

• https://github.com/Yomguithereal/baobab

• https://github.com/uberVU/react-guide/blob/master/props-vs-state.md

• http://jaysoo.ca/2015/02/06/what-the-flux/

• https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

• https://github.com/wiktor256/react-state-router