View
317
Download
1
Category
Preview:
Citation preview
© 2017 Sencha Inc. • CONFIDENTIAL •
Introducing ExtReact: Adding
Powerful Sencha Components
to React Apps
Mark Brocato
Engineering Director, Sencha
@mockaroodev
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext JS
Ext JS
Components
Ext JS Framework
© 2017 Sencha Inc. • CONFIDENTIAL •
React: A Component Framework w/o Components
Ext JS
Components
Ext JS Framework
ExtReact
React.js
© 2017 Sencha Inc. • CONFIDENTIAL •
ExtReact
Use All Ext JS Components in React
© 2017 Sencha Inc. • CONFIDENTIAL •
Motivation for ExtReact
• No complete component libraries available for React
• Dependency fatigue
• Form without function
• Head start
• Data-driven, enterprise apps
© 2017 Sencha Inc. • CONFIDENTIAL •
ExtReact: 100+ Components
• Grid
• List
• Tree
• Calendar
• Layouts
• Form Fields
• Animations
• Charts
• D3 Visualizations
© 2017 Sencha Inc. • CONFIDENTIAL •
@extjs/reactor
GitHub: extjs-reactor
© 2017 Sencha Inc. • CONFIDENTIAL •
ExtReact vs Ext JS + React
ExtReact
• Separate license from Ext JS (annual subscription, perpetual distribution rights)
• Streamlined installation (NPM)• Modern toolkit only (Ext JS 6.5)
Ext JS + Reactor
• Use your existing Ext JS license• Traditional Ext JS installation process• Modern + Classic toolkits
© 2017 Sencha Inc. • CONFIDENTIAL •
ExtReact Grid
<Grid title="Stock Prices" store={this.store}>
<Column text="Company" dataIndex="name"/>
<Column text="Price" dataIndex="price" formatter='usMoney'/>
<Column text="Change" dataIndex="priceChange"/>
<Column text="% Change" dataIndex="priceChangePct"/>
<Column text="Last Updated" dataIndex="lastChange" formatter='date("m/d/Y")'/>
</Grid>
© 2017 Sencha Inc. • CONFIDENTIAL •
ExtReact for Ext JS Developers
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext.create({
xtype: 'list',
store: contacts,
grouped: true
});
Ext JS ExtReact
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext.create({
xtype: 'list',
store: contacts,
grouped: true
});
import { List } from '@extjs/ext-react';
<List
store={contacts}
grouped
/>
Ext JS ExtReact
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext.create({
xtype: 'list',
store: contacts,
grouped: true,
listeners: {
itemtap: function(list, index, target, record) {
console.log(`Tapped ${record.get('name')}`)
}
}
});
import { List } from '@extjs/ext-react';
<List
store={contacts}
grouped
/>
Ext JS ExtReact
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext.create({
xtype: 'list',
store: contacts,
grouped: true,
listeners: {
itemtap: function(list, index, target, record) {
console.log(`Tapped ${record.get('name')}`)
}
}
});
import { List } from '@extjs/ext-react';
<List
store={contacts}
grouped
onItemTap={(list, index, target, record) => {
console.log(`Tapped ${record.get('name')}`)
}}
/>
Ext JS ExtReact
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext.create({
xtype: 'list',
store: contacts,
grouped: true,
listeners: {
itemtap: function(list, index, target, record) {
console.log(`Tapped ${record.get('name')}`)
},
show: {
single: true,
fn: function() {
// load store
}
}
}
});
import { List } from '@extjs/ext-react';
<List
store={contacts}
grouped
onItemTap={(list, index, target, record) => {
console.log(`Tapped ${record.get('name')}`)
}}
/>
Ext JS ExtReact
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext.create({
xtype: 'list',
store: contacts,
grouped: true,
listeners: {
itemtap: function(list, index, target, record) {
console.log(`Tapped ${record.get('name')}`)
},
show: {
single: true,
fn: function() {
// load store
}
}
}
});
import { List } from '@extjs/ext-react';
<List
store={contacts}
grouped
onItemTap={(list, index, target, record) => {
console.log(`Tapped ${record.get('name')}`)
}}
onShow={{
single: true,
fn: () => {
// load store
}
}}
/>
Ext JS ExtReact
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext.create({
xtype: 'list',
store: contacts,
grouped: true,
listeners: {
itemtap: function(list, index, target, record) {
console.log(`Tapped ${record.get('name')}`)
},
show: {
single: true,
fn: function() {
// load store
}
}
},
itemTpl: (
'<div>' +
'<div>{firstName} {lastName}</div>' +
'<div>{title}</div>' +
'</div>'
)
});
import { List } from '@extjs/ext-react';
<List
store={contacts}
grouped
onItemTap={(list, index, target, record) => {
console.log(`Tapped ${record.get('name')}`)
}}
onShow={{
single: true,
fn: () => {
// load store
}
}}
/>
Ext JS ExtReact
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext.create({
xtype: 'list',
store: contacts,
grouped: true,
listeners: {
itemtap: function(list, index, target, record) {
console.log(`Tapped ${record.get('name')}`)
},
show: {
single: true,
fn: function() {
// load store
}
}
},
itemTpl: (
'<div>' +
'<div>{firstName} {lastName}</div>' +
'<div>{title}</div>' +
'</div>'
)
});
import { List } from '@extjs/ext-react';
<List
store={contacts}
grouped
onItemTap={(list, index, target, record) => {
console.log(`Tapped ${record.get('name')}`)
}}
onShow={{
single: true,
fn: () => {
// load store
}
}}
itemTpl={data => (
<div>
<div>{data.firstName} {data.lastName}</div>
<div>{data.title}</div>
</div>
)}
/>
Ext JS ExtReact
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext.create({
xtype: 'list',
store: contacts,
grouped: true,
listeners: {
...
},
itemTpl: (
'<div>' +
'<div>{firstName} {lastName}</div>' +
'<div>{title}</div>' +
'</div>'
)
items: [{
xtype: 'toolbar',
docked: 'top'
items: [{
xtype: 'button',
text: 'Refresh'
}]
}]
});
import { List } from '@extjs/ext-react';
<List
store={contacts}
grouped
onItemTap={(list, index, target, record) => {
console.log(`Tapped ${record.get('name')}`)
}}
onShow={{
single: true,
fn: () => {
// load store
}
}}
itemTpl={data => (
<div>
<div>{data.firstName} {data.lastName}</div>
<div>{data.title}</div>
</div>
)}
/>
Ext JS ExtReact
© 2017 Sencha Inc. • CONFIDENTIAL •
Ext.create({
xtype: 'list',
store: contacts,
grouped: true,
listeners: {
...
},
itemTpl: (
'<div>' +
'<div>{firstName} {lastName}</div>' +
'<div>{title}</div>' +
'</div>'
)
items: [{
xtype: 'toolbar',
docked: 'top'
items: [{
xtype: 'button',
text: 'Refresh'
}]
}]
});
20
import { List, Toolbar, Button } from '@extjs/ext-react';
<List
store={contacts}
grouped
...
itemTpl={data => (
<div>
<div>{firstName} {lastName}</div>
<div>{title}</div>
</div>
)}
>
<Toolbar>
<Button
text="Refresh"
/>
</Toolbar>
</List>
Ext JS ExtReact
© 2017 Sencha Inc. • CONFIDENTIAL •
ExtReact Components are Themable
• Each can be extended using SASS or Sencha Themer
Triton Material iOS
© 2017 Sencha Inc. • CONFIDENTIAL •
Sencha Themer
22
© 2017 Sencha Inc. • CONFIDENTIAL •
FAQ
• Controllers
• ViewModels
How much of the Ext JS framework will I use?
Components
Stores
ModelsGrid, Tree, Calendar, etc…
Flux (Redux, MobX, et al...)
© 2017 Sencha Inc. • CONFIDENTIAL •
Components Virtual DOM DOMExtReact?
Ext JS
FAQ
Does ExtReact use the Virtual DOM?
© 2017 Sencha Inc. • CONFIDENTIAL •
FAQ
Can I reuse components from pure Ext JS apps?
import { reactify } from '@extjs/reactor';
const MyCustomComponent = reactify(MyPackage.MyCustomComponent);
...
render() {
return <MyCustomComponent ... />
}
© 2017 Sencha Inc. • CONFIDENTIAL •
ExtReact: Getting Set Up
© 2017 Sencha Inc. • CONFIDENTIAL •
Sign up for a trial at sencha.com
npm login --registry=http://npm.sencha.com --scope=@extjs
© 2017 Sencha Inc. • CONFIDENTIAL •
Use Yeoman to create new apps
npm install –g yo @extjs/generator-ext-react
yo @extjs/ext-react
© 2017 Sencha Inc. • CONFIDENTIAL •
GitHub: sencha/extjs-reactor
packages/reactor-modern-boilerplate
packages/reactor-classic-boilerplate
© 2017 Sencha Inc. • CONFIDENTIAL •
Adding ExtReact to an Existing React App
• npm install --save @extjs/reactor @extjs/ext-react
• npm install --save-dev @extjs/reactor-webpack-plugin @extjs/reactor-babel-plugin
© 2017 Sencha Inc. • CONFIDENTIAL •
Adding Ext JS to an Existing React App
• npm install --save @extjs/reactor
• npm install --save-dev @extjs/reactor-webpack-plugin @extjs/reactor-babel-plugin
• Download and unzip Ext JS from sencha.com
© 2017 Sencha Inc. • CONFIDENTIAL •
Webpack
import ExtReactWebpackPlugin from '@extjs/reactor-webpack-plugin’
...
plugins: [
new ExtReactWebpackPlugin({
theme: 'theme-material'
}),
]
© 2017 Sencha Inc. • CONFIDENTIAL •
Webpack
import ExtReactWebpackPlugin from '@extjs/reactor-webpack-plugin’
...
plugins: [
new ExtReactWebpackPlugin({
theme: 'theme-material',
// not needed for ExtReact
sdk: '/path/to/extjs',
toolkit: 'modern'
packages: ['charts']
}),
]
© 2017 Sencha Inc. • CONFIDENTIAL •
Babel
.babelrc
{
"plugins": [
"@extjs/reactor-babel-plugin"
]
}
© 2017 Sencha Inc. • CONFIDENTIAL •
React App Launch
import React from ’react';
import App from './App'; // app components
import { launch } from '@extjs/reactor';
launch(<App/>); // replaces ReactDOM.render(<App/>, document.getElementById(‘root’))
© 2017 Sencha Inc. • CONFIDENTIAL •
Live Demos
© 2017 Sencha Inc. • CONFIDENTIAL •
Sencha Fiddle
https://fiddle.sencha.com/?extreact
© 2017 Sencha Inc. • CONFIDENTIAL •
Q&A
© 2017 Sencha Inc. • CONFIDENTIAL •
Thank You!
Recommended