Sviluppare applicazioni client, server e mobile con React Jiayi Hu, Maksim Sinik, Michele Stieven, Fabio Biondi
FABIO BIONDI FREELANCE fabiobiondi.io
EX FLASH-FLEX-AIR
 CERTIFIED INSTRUCTOR :°( 2002-2012
I also love: Typescript, Redux, RxJS, D3.js, CreateJS,Arduino, …. ANGULAR & REACT DEVELOPER &TRAINER
COMMUNITIES
ANGULAR 
 DEVELOPER ITALIANI JAVASCRIPT 
 DEVELOPER ITALIANI REACT 
 DEVELOPER ITALIANI
PARTNERS
ONE YEAR SUBSCRIPTION (for 2 attendees)
Javascript ES6 : La guida mancante in italiano Corso completo di sviluppo web: crea da zero il tuo business
La Fabbrica di innovazione e sviluppo tecnologico dei servizi core per le aziende. INutile è anche il tuo successo professionale dei prossimi anni 
 www.inattivo.com Progetto INutile
• Il marketplace che conne0e aziende e freelancer digitali • Usa l’Ar:ficial Intelligence per la creazione di team di freelancer • Un workspace Agile per la ges:one della collaborazione azienda - team • Il primo marketplace collegato ad un ufficio 3D in Virtual Reality • Iscrivi: alla newsle0er su h0ps://coderblock.com o sulla pagina facebook per testare la pia0aforma in closed beta e ricevere i primi premi! Il recruitment ai tempi del remote working.
IL PROGRAMMA DI OGGI
// 09:50-10:30
 (JsxTopLevelAPI) => <FabioBiondi />
 
 // 10:30-11:10
 (ReactNative) => <MicheleStieven />
 
 // 11:10-11:40
 (coffee) => ‘networking’ // 11:40-12:20
 (NextJS) => <MaksimSinik />
 
 // 12:20-13:00
 (customRenderer) => <JiayiHu />
 

<JSX> Top-Level API vs Fabio Biondi
JSX • Many Angular / Javascript developers 
 think JSX is sh*t • Why? Because of the HTML, CSS and JS “mix”
 (in the same file)
JSX In my opinion 
 JSX is one of the most interesting features in React 
 thanks to its flexibility
JSX • JSX is a preprocessor step that adds XML syntax to JavaScript • So, you can mix HTML, JS and CSS • A simple way to update dynamically DOM • You can definitely use React without JSX (thanks to React API) 
 (but JSX makes React a lot more elegant)
GOAL
Component-based approach
<Widget> should contain several contents: 
 React Components or HTML element
PART 1 JSXVS REACT TOP-LEVEL API
COMPONENTS: JSX import React from ‘react’;
 export const Text = () => { return <div style={{color: 'red'}}>Hello</div>; }; <Text /> HOWTO USE: COMPONENT: <div>Hello</div> OUTPUT:
COMPONENT: COMPONENTS: REACT API export const Text = () => { return React.createElement( 'div', { style: { color: 'green' } }, 'Hello'); }; <Text /> HOWTO USE: <div>Hello</div> OUTPUT:
DYNAMIC CONTENT: JSX export const Text = props => { return <div>{props.children}</div> }; export const Home = () => { return <Text>Hello World</Text> }; HOWTO USE: COMPONENT:
DYNAMIC CONTENT: API export const Home = () => { return <Text>Hello World</Text> }; HOWTO USE: COMPONENT: export const Text = props => { return React.createElement('div', null, props.children); };
REAL WORLD EXAMPLE <Text>React</Text> <Text inline>Hello</Text> <Text inline>World</Text> COMPONENT:export const Text = props => { const type = props.inline ? 'span' : 'div'; return React.createElement( type, null, props.children ); };
OUTPUT: DEVTOOLS
PART 2 <Widget /> component
<Dashboard> <Widget> COMPONENT: export const Dashboard = () => { return ( <div> <Widget title=“Temperatures” /> <Widget title=“Profile” /> <Widget title=“Anything" /> </div> ) }; 1/2
COMPONENT: export const Dashboard = () => { const destroyWidget = () => console.log(‘destroy widget'); const toggleOptions = () => console.log(‘toggle options’); 
 return ( <div> <Widget title="Temperatures" onClose={() => destroyWidget()} onToggleOptions={() => toggleOptions()} /> </div> ) <Dashboard> <Widget> 2/2
FLOW
CREATE A CARD / WIDGET IN BOOTSTRAP 4 COMPONENT: <div class="card"> <div class="card-header">Widget Title</div> <div class="card-body"> Widget Content </div> </div>
<Widget /> COMPONENT: export const Widget = props => { return ( <div className="card"> <div className="card-header"> <span>{props.title}</span> <i className="fa fa-gear" onClick={props.onToggleOptions}></i> <i className="fa fa-times" onClick={props.onClose}></i> </div> <div className="card-body"> ...Widget Content... </div> </div> ) }
PART 3 SPLIT IN COMPONENTS
COMPONENT TREE 1/2
COMPONENT TREE 2/2
<Widget> <WidgetBar> COMPONENT: export const Widget = props => { return ( <div className="card"> <WidgetBar title={props.title} onToggleOptions={props.onToggleOptions} onClose={props.onClose} /> <div className="card-body"> Widget Body </div> </div> ) };
COMPONENT: const WidgetBar = props => { return ( <div className="card-header"> <span>{props.title}</span> <i className="fa fa-gear pull-right" onClick={props.onToggleOptions} /> <i className="fa fa-times pull-right" onClick={props.onClose} /> </div> ) } <WidgetBar>
PART 4
 <WidgetBody>
type AS CLASS NAME <Widget title="Temperatures" type={Chart} config={temperatures} /> 
 <Widget title=“User Profile" type={Profile} userID="123"/> NOTE: each widget needs different properties to work
WidgetBody Content const Chart = props => ( <h1 className=“m-2"> I'm a chart {props.config.data.length} </h1> ); const Profile = props => ( <div className="m-2"> <input type="text" defaultValue={props.userID}/> ... </div> ); const Any = props => `I’m another component`;
COMPONENT: export const Widget = props => { return ( <div className="card"> <WidgetBar title={props.title} onToggleOptions={props.onToggleOptions} onClose={props.onClose} /> <WidgetBody {...props} /> </div> ) }; NOTE: we use spread operator … to pass all props to a component <Widget> <WidgetBody>
<WidgetBody> const WidgetBody = props => { const { type, title, onToggleOptions, onClose, ...others } = props; 
 return React.createElement(type, {...others}, null); } NOTE: we use ES6 destructuring
PART 5 type AS STRING (USEFUL WHEN WIDGET CONFIGURATION
 IS LOADED FROM JSON)
HOWTO USE COMPONENT: <Widget title=“Temperatures" type="Chart" config={myData} 
 onClose={() => destroyWidget()} onShowOptions={() => openOptions()} /> <Widget title="MyProfile" type="Profile" user=“123"
 onClose={() => destroyWidget()} onShowOptions={() => openOptions()} /> <Widget title=“Any Component" type="Any"/>
or by using .map() COMPONENT: props.widgets.map(item => ( <Widget key={item.id} {...item} onClose={() => destroyWidget()} onShowOptions={() => openOptions()} />
 );
<widgetBody>: JSX version COMPONENT: const WidgetBody = props => { switch(props.type) { case 'Chart': return <Chart {...props} />; case 'Profile': return <Profile {...props} />; case 'Any': return <Any {...props} />; default: return <h3>You forgot type</h3>; } };
<WidgetBody>: REACT API/eval version COMPONENT: const WidgetBody = props => { const { type, ...others } = props; 
 return React.createElement( eval(type), {...others}, null ) } If you run eval() someone could run malicious code on the user's machine
<widgetBody>: API & Map() version COMPONENT: const WidgetBody = props => { const { type, ...others } = props; return React.createElement(
 components.get(type), {...others}, null ) } const components = new Map(); components.set('Chart', Chart); components.set('Profile', Profile); components.set('Any', Any);
CAN I DOTHE SAME 
 IN ANGULAR?

 CREATING A DIRECTIVE:
 <div [widgetBody]=“myComponent” (close)=“destroy()” (toggleOptions)=“toggleMenu()”>
import { ComponentRef, ComponentFactoryResolver, Directive, ElementRef, Input, OnDestroy, ViewContainerRef } from '@angular/core';
 @Directive({ selector: '[widgetBody]' }) export class WidgetBodyDirective implements OnDestroy { @Input() set widgetBody(component: WidgetComponent) { this.view.clear(); if (component) { let factory = this.resolver.resolveComponentFactory(component.type); this.ref = this.view.createComponent(factory); for (let key in component.payload) { this.ref.instance[key] = component.payload[key]; } } }
 private ref: ComponentRef<any>; constructor( private view: ViewContainerRef, private resolver: ComponentFactoryResolver) { } ngOnDestroy() { if (this.ref) { this.ref.destroy(); } } }
<source-code>
THANKS fabiobiondi.io
JOIN OUR COMMUNITIES ANGULAR 
 DEVELOPER ITALIANI JAVASCRIPT 
 DEVELOPER ITALIANI REACT 
 DEVELOPER ITALIANI

React: JSX and Top Level API

  • 2.
    Sviluppare applicazioni client,server e mobile con React Jiayi Hu, Maksim Sinik, Michele Stieven, Fabio Biondi
  • 3.
  • 4.
  • 5.
    I also love:Typescript, Redux, RxJS, D3.js, CreateJS,Arduino, …. ANGULAR & REACT DEVELOPER &TRAINER
  • 6.
  • 7.
    ANGULAR 
 DEVELOPER ITALIANI JAVASCRIPT
 DEVELOPER ITALIANI REACT 
 DEVELOPER ITALIANI
  • 9.
  • 10.
  • 11.
    Javascript ES6 :La guida mancante in italiano Corso completo di sviluppo web: crea da zero il tuo business
  • 12.
    La Fabbrica diinnovazione e sviluppo tecnologico dei servizi core per le aziende. INutile è anche il tuo successo professionale dei prossimi anni 
 www.inattivo.com Progetto INutile
  • 13.
    • Il marketplaceche conne0e aziende e freelancer digitali • Usa l’Ar:ficial Intelligence per la creazione di team di freelancer • Un workspace Agile per la ges:one della collaborazione azienda - team • Il primo marketplace collegato ad un ufficio 3D in Virtual Reality • Iscrivi: alla newsle0er su h0ps://coderblock.com o sulla pagina facebook per testare la pia0aforma in closed beta e ricevere i primi premi! Il recruitment ai tempi del remote working.
  • 14.
  • 15.
    // 09:50-10:30
 (JsxTopLevelAPI) =><FabioBiondi />
 
 // 10:30-11:10
 (ReactNative) => <MicheleStieven />
 
 // 11:10-11:40
 (coffee) => ‘networking’ // 11:40-12:20
 (NextJS) => <MaksimSinik />
 
 // 12:20-13:00
 (customRenderer) => <JiayiHu />
 

  • 16.
  • 17.
    JSX • Many Angular/ Javascript developers 
 think JSX is sh*t • Why? Because of the HTML, CSS and JS “mix”
 (in the same file)
  • 18.
    JSX In my opinion
 JSX is one of the most interesting features in React 
 thanks to its flexibility
  • 19.
    JSX • JSX isa preprocessor step that adds XML syntax to JavaScript • So, you can mix HTML, JS and CSS • A simple way to update dynamically DOM • You can definitely use React without JSX (thanks to React API) 
 (but JSX makes React a lot more elegant)
  • 20.
  • 21.
  • 22.
    <Widget> should containseveral contents: 
 React Components or HTML element
  • 23.
    PART 1 JSXVS REACTTOP-LEVEL API
  • 24.
    COMPONENTS: JSX import Reactfrom ‘react’;
 export const Text = () => { return <div style={{color: 'red'}}>Hello</div>; }; <Text /> HOWTO USE: COMPONENT: <div>Hello</div> OUTPUT:
  • 25.
    COMPONENT: COMPONENTS: REACT API exportconst Text = () => { return React.createElement( 'div', { style: { color: 'green' } }, 'Hello'); }; <Text /> HOWTO USE: <div>Hello</div> OUTPUT:
  • 26.
    DYNAMIC CONTENT: JSX exportconst Text = props => { return <div>{props.children}</div> }; export const Home = () => { return <Text>Hello World</Text> }; HOWTO USE: COMPONENT:
  • 27.
    DYNAMIC CONTENT: API exportconst Home = () => { return <Text>Hello World</Text> }; HOWTO USE: COMPONENT: export const Text = props => { return React.createElement('div', null, props.children); };
  • 28.
    REAL WORLD EXAMPLE <Text>React</Text> <Textinline>Hello</Text> <Text inline>World</Text> COMPONENT:export const Text = props => { const type = props.inline ? 'span' : 'div'; return React.createElement( type, null, props.children ); };
  • 29.
  • 30.
  • 31.
    <Dashboard> <Widget> COMPONENT: export constDashboard = () => { return ( <div> <Widget title=“Temperatures” /> <Widget title=“Profile” /> <Widget title=“Anything" /> </div> ) }; 1/2
  • 32.
    COMPONENT: export const Dashboard= () => { const destroyWidget = () => console.log(‘destroy widget'); const toggleOptions = () => console.log(‘toggle options’); 
 return ( <div> <Widget title="Temperatures" onClose={() => destroyWidget()} onToggleOptions={() => toggleOptions()} /> </div> ) <Dashboard> <Widget> 2/2
  • 33.
  • 34.
    CREATE A CARD/ WIDGET IN BOOTSTRAP 4 COMPONENT: <div class="card"> <div class="card-header">Widget Title</div> <div class="card-body"> Widget Content </div> </div>
  • 35.
    <Widget /> COMPONENT: export constWidget = props => { return ( <div className="card"> <div className="card-header"> <span>{props.title}</span> <i className="fa fa-gear" onClick={props.onToggleOptions}></i> <i className="fa fa-times" onClick={props.onClose}></i> </div> <div className="card-body"> ...Widget Content... </div> </div> ) }
  • 36.
    PART 3 SPLIT INCOMPONENTS
  • 37.
  • 38.
  • 39.
    <Widget> <WidgetBar> COMPONENT: export constWidget = props => { return ( <div className="card"> <WidgetBar title={props.title} onToggleOptions={props.onToggleOptions} onClose={props.onClose} /> <div className="card-body"> Widget Body </div> </div> ) };
  • 40.
    COMPONENT: const WidgetBar =props => { return ( <div className="card-header"> <span>{props.title}</span> <i className="fa fa-gear pull-right" onClick={props.onToggleOptions} /> <i className="fa fa-times pull-right" onClick={props.onClose} /> </div> ) } <WidgetBar>
  • 41.
  • 42.
    type AS CLASSNAME <Widget title="Temperatures" type={Chart} config={temperatures} /> 
 <Widget title=“User Profile" type={Profile} userID="123"/> NOTE: each widget needs different properties to work
  • 43.
    WidgetBody Content const Chart= props => ( <h1 className=“m-2"> I'm a chart {props.config.data.length} </h1> ); const Profile = props => ( <div className="m-2"> <input type="text" defaultValue={props.userID}/> ... </div> ); const Any = props => `I’m another component`;
  • 44.
    COMPONENT: export const Widget= props => { return ( <div className="card"> <WidgetBar title={props.title} onToggleOptions={props.onToggleOptions} onClose={props.onClose} /> <WidgetBody {...props} /> </div> ) }; NOTE: we use spread operator … to pass all props to a component <Widget> <WidgetBody>
  • 45.
    <WidgetBody> const WidgetBody =props => { const { type, title, onToggleOptions, onClose, ...others } = props; 
 return React.createElement(type, {...others}, null); } NOTE: we use ES6 destructuring
  • 47.
    PART 5 type ASSTRING (USEFUL WHEN WIDGET CONFIGURATION
 IS LOADED FROM JSON)
  • 48.
    HOWTO USE COMPONENT: <Widget title=“Temperatures" type="Chart" config={myData}
 onClose={() => destroyWidget()} onShowOptions={() => openOptions()} /> <Widget title="MyProfile" type="Profile" user=“123"
 onClose={() => destroyWidget()} onShowOptions={() => openOptions()} /> <Widget title=“Any Component" type="Any"/>
  • 49.
    or by using.map() COMPONENT: props.widgets.map(item => ( <Widget key={item.id} {...item} onClose={() => destroyWidget()} onShowOptions={() => openOptions()} />
 );
  • 50.
    <widgetBody>: JSX version COMPONENT: constWidgetBody = props => { switch(props.type) { case 'Chart': return <Chart {...props} />; case 'Profile': return <Profile {...props} />; case 'Any': return <Any {...props} />; default: return <h3>You forgot type</h3>; } };
  • 51.
    <WidgetBody>: REACT API/evalversion COMPONENT: const WidgetBody = props => { const { type, ...others } = props; 
 return React.createElement( eval(type), {...others}, null ) } If you run eval() someone could run malicious code on the user's machine
  • 52.
    <widgetBody>: API &Map() version COMPONENT: const WidgetBody = props => { const { type, ...others } = props; return React.createElement(
 components.get(type), {...others}, null ) } const components = new Map(); components.set('Chart', Chart); components.set('Profile', Profile); components.set('Any', Any);
  • 54.
    CAN I DOTHESAME 
 IN ANGULAR?
  • 55.
  • 56.
    import { ComponentRef, ComponentFactoryResolver,Directive, ElementRef, Input, OnDestroy, ViewContainerRef } from '@angular/core';
 @Directive({ selector: '[widgetBody]' }) export class WidgetBodyDirective implements OnDestroy { @Input() set widgetBody(component: WidgetComponent) { this.view.clear(); if (component) { let factory = this.resolver.resolveComponentFactory(component.type); this.ref = this.view.createComponent(factory); for (let key in component.payload) { this.ref.instance[key] = component.payload[key]; } } }
 private ref: ComponentRef<any>; constructor( private view: ViewContainerRef, private resolver: ComponentFactoryResolver) { } ngOnDestroy() { if (this.ref) { this.ref.destroy(); } } }
  • 58.
  • 59.
  • 60.
    JOIN OUR COMMUNITIES ANGULAR
 DEVELOPER ITALIANI JAVASCRIPT 
 DEVELOPER ITALIANI REACT 
 DEVELOPER ITALIANI