SlideShare a Scribd company logo
React: JSX and Top Level API
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
React: JSX and Top Level API
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
React: JSX and Top Level API
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);
React: JSX and Top Level API
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();
}
}
}
React: JSX and Top Level API
<source-code>
THANKS
fabiobiondi.io
JOIN OUR COMMUNITIES
ANGULAR 

DEVELOPER ITALIANI
JAVASCRIPT 

DEVELOPER ITALIANI
REACT 

DEVELOPER ITALIANI

More Related Content

React: JSX and Top Level API

  • 2. Sviluppare applicazioni client, server e mobile con React Jiayi Hu, Maksim Sinik, Michele Stieven, Fabio Biondi
  • 5. I also love: Typescript, Redux, RxJS, D3.js, CreateJS,Arduino, …. ANGULAR & REACT DEVELOPER &TRAINER
  • 7. ANGULAR 
 DEVELOPER ITALIANI JAVASCRIPT 
 DEVELOPER ITALIANI REACT 
 DEVELOPER ITALIANI
  • 11. Javascript ES6 : La guida mancante in italiano Corso completo di sviluppo web: crea da zero il tuo business
  • 12. 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
  • 13. • 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.
  • 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 />
 

  • 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 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)
  • 20. GOAL
  • 22. <Widget> should contain several contents: 
 React Components or HTML element
  • 23. PART 1 JSXVS REACT TOP-LEVEL API
  • 24. COMPONENTS: JSX import React from ‘react’;
 export const Text = () => { return <div style={{color: 'red'}}>Hello</div>; }; <Text /> HOWTO USE: COMPONENT: <div>Hello</div> OUTPUT:
  • 25. COMPONENT: COMPONENTS: REACT API export const Text = () => { return React.createElement( 'div', { style: { color: 'green' } }, 'Hello'); }; <Text /> HOWTO USE: <div>Hello</div> OUTPUT:
  • 26. DYNAMIC CONTENT: JSX export const Text = props => { return <div>{props.children}</div> }; export const Home = () => { return <Text>Hello World</Text> }; HOWTO USE: COMPONENT:
  • 27. 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); };
  • 28. 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 ); };
  • 30. PART 2 <Widget /> component
  • 31. <Dashboard> <Widget> COMPONENT: export const Dashboard = () => { 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. FLOW
  • 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 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> ) }
  • 36. PART 3 SPLIT IN COMPONENTS
  • 39. <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> ) };
  • 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>
  • 42. 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
  • 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 AS STRING (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: 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>; } };
  • 51. <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
  • 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 DOTHE SAME 
 IN ANGULAR?
  • 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(); } } }
  • 60. JOIN OUR COMMUNITIES ANGULAR 
 DEVELOPER ITALIANI JAVASCRIPT 
 DEVELOPER ITALIANI REACT 
 DEVELOPER ITALIANI