SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

42
Ext JS + React A Match Made in UX Heaven Mark Brocato Sr. Engineering Manager, Sencha

Transcript of SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Page 1: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Ext JS + ReactA Match Made in UX Heaven

Mark BrocatoSr. Engineering Manager, Sencha

Page 2: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

My Journey to React

Page 3: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

My Journey to React

Page 4: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
Page 5: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
Page 6: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Scenario Builder

Page 7: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

My Journey to React

Page 8: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

My Journey to React

Page 9: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

My Journey to React

Page 10: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

My Journey to React

Page 11: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

React Primer

• A JavaScript library for building user interfaces

• React is the just the V in MVC

• Solve one problem: Build large applications with data that changes over time.

Page 12: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

React Components

Componentdata

HTML

Page 13: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Views as Pure Functions

dataHTMLFunction

Page 14: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Views as Componentsimport React, { Component } from 'react'; class NewsFeed extends Component { render() { const { news } = this.props; return ( <ul> { news.map(story => ( <li> <div className="title">{story.title}</div> <div>by {story.author}</div> </li> )) } </ul> ) } }

Page 15: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Views as Pure Functions

function NewsFeed({ news }) { return ( <ul> { news.map(story => ( <li> <div className="title">{story.title}</div> <div>by {story.author}</div> </li> )) } </ul> ) }

Page 16: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

JSX

<div className="title">{story.title}</div>

Page 17: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

JSX

<div className="title">{story.title}</div>

React.createElement('div', { className: 'title'}, store.title)

Page 18: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Views as Components

function NewsFeed({ news }) { return ( React.createElement('ul', {}, news.map(story => { return React.createElement('li', {}, [ React.createElement('div', { className: 'title' }, store.title), React.createElement('div', { }, `by ${store.author}`) ]) })); ) }

Page 19: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

React’s One-Way Data Flow (Flux)

Store

Component Component Component

Component Component Component Component

dataAPI

Page 20: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Virtual DOM to the Rescue

Page 21: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

React and Ext JS Similarities

• Ext.Component

• configs

• items: []

• React.Component

• props

• children

Page 22: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

What’s Missing?

✔ Routing: react-router✔ Architecture: redux

Components

Page 23: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
Page 24: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

@extjs/reactor

Page 25: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

React Hello Worldimport React from 'react'; import ReactDOM from 'react-dom'; ReactDOM.render( ( <div> Hello World! </div> ), document.getElementById('root') );

Page 26: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

React Hello World w/ Ext JSimport React from 'react'; import ReactDOM from 'react-dom'; import install from ’@extjs/reactor'; install(); Ext.onReady(() => { ReactDOM.render( ( <x-panel title="Ext JS in React"> Hello World! </x-panel> ), document.getElementById('root') ); });

Page 27: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

@extjs/reactor

• Use any xtype as a JSX tag.

• Mix and match HTML and Ext JS

import React from 'react'; import ReactDOM from 'react-dom'; import install from ’@extjs/reactorjs'; install(); Ext.onReady(() => { ReactDOM.render( ( <x-panel title="Ext JS in React"> Hello World! </x-panel> ), document.getElementById('root') ); });

Ext.create({ xtype: 'panel', title: 'Ext JS in React', html: 'Hello World!'});

Page 28: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Responding to Events

• All props starting with “on” are automatically converted to Ext JS event listeners

• You can also specify event handlers using a listeners prop, just like in traditional Ext JS

import React, { Component } from 'react'; class MyComponent extends Component { onSliderChange(slider, value) { console.log('value', value); } render() { return ( <x-slider

onChange={this.onSliderChange.bind(this)}/>

) } }

Page 29: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Responding to Events

• All props starting with “on” are automatically converted to Ext JS event listeners

• You can also specify event handlers using a listeners prop, just like in traditional Ext JS

import React, { Component } from 'react'; class MyComponent extends Component { onSliderChange(slider, value) { console.log('value', value); } render() { return ( <x-slider

onChange={this.onSliderChange.bind(this)}/>

) } }

Ext.create({ xtype: 'slider', listeners: {

change: this.onSliderChange }});

Page 30: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Component Refs

• As with DOM elements, you can access Ext components by adding a “ref” prop.

• Here this.refs.slider is an instance of Ext.slider.Slider

import React, { Component } from 'react'; class MyComponent extends Component { onSliderChange(slider, value) { console.log('value', this.refs.slider.getValue()); } render() { return ( <x-slider

ref="slider" onChange={this.onSliderChange.bind(this)}

/> ) } }

Page 31: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

More Complex Configs

• It’s all just JavaScript.

• React props => Ext JS configs

class MyComponent extends Component { render() { return ( <x-grid plugins={[ { type: 'columnresizing' } ]} columns={[ { text: 'Name', dataIndex: 'name' }, { text: 'Email', dataIndex: 'email' } ]} store={{ data: [ ...

] }} /> ) } }

Page 32: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Layouts

• Work like you’d expect

class MyComponent extends Component { render() { return ( <x-container layout="hbox"> <x-button text="Left"/> <x-button text="Right"/> </x-container> ) } }

Page 33: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Layouts

• Work like you’d expect

class MyComponent extends Component { render() { return ( <x-container layout="hbox"> <x-button text="Left"/> <x-button text="Right"/> </x-container> ) } }

Ext.create({ xtype: 'container', layout: 'hbox', items: [ { xtype: 'button', text: 'Left' }, { xtype: 'button', text: 'Right' } ]});

Page 34: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Updates

• When a prop changes, @extjs/reactor automatically calls the corresponding setter method to update your component’s configs.

class MyComponent extends Component {

constructor(props) { super(props); this.state = { dirty: true }; } render() { const text = this.state.dirty ? "Save Changes" : "Changes Saved"; return ( <x-button text={text} handler={this.onClick.bind(this)} /> ) } onClick() { this.setState({ dirty: false }); }

}

Page 35: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Updates

• When a prop changes, @extjs/reactor automatically calls the corresponding setter method to update your component’s configs.

class MyComponent extends Component {

constructor(props) { super(props); this.state = { dirty: true }; } render() { const text = this.state.dirty ? "Save Changes" : "Changes Saved"; return ( <x-button text={text} handler={this.onClick.bind(this)} /> ) } onClick() { this.setState({ dirty: false }); }

}

button.setText(text);

Page 36: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Summing Up

props configs

on/A-Z/ listeners

child elements items: []

updates setter calls

Page 37: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

@extjs/reactor-webpack-plugin

Page 38: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Setting up your React app for Ext JS

ext-all.js reactor-webpack-plugin

Page 39: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Automatic Usage Detectionimport React, { Component } from 'react'; Ext.require('Ext.window.Toast'); export default class MyDialog extends Component { constructor(props) { super(props); this.store = Ext.create('Ext.data.Store', { ... }); } render ( <x-window> <x-grid ... /> </x-window> ) }

ext.js

ext.css

Page 40: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

Configure Theme, Toolkit, and Packages

const ExtJSReactorWebpackPlugin = require('@extjs/reactor-webpack-plugin'); module.exports = { ... plugins: [ new ExtJSReactorWebpackPlugin({ sdk: 'ext', // relative or full path to Ext JS SDK toolkit: 'modern', theme: 'theme-material', packages: ['charts'], output: path.join('build', 'ext') }) ] ... };

Page 41: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

@extjs/reactor-boilerplate

Page 42: SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato

reactor-boilerplate