Abhishek Yadav
Co-organizer: Chennai.js
JSX
// This should be counted as valid javascript
var el = <div>Hello World</div>;
The idea
So that -
=> We can write HTML syntax within Javascript
=> => That gets converted to equivalent real HTML when needed
// This should place the div within document
var el = <div>Hello World</div>;
ReactDOM.render(el, document)
The idea
<!-- A more sane example -->
<div id='root'></div>
<script type='text/babel'>
const rootElement = document.getElementById('root')
const el = <div>Hello World</div>;
ReactDOM.render(el, rootElement)
</script>
The idea
Create that Hello World element,
insert it inside the root element
<!-- Just like this ? Jquery FTW !! -->
<div id='root'></div>
<script type='text/babel'>
const el = $('<div>Hello World</div>')
$('#root').html(el)
</script>
The idea
<!-- Or even plain Javascript -->
<div id='root'></div>
<script type='text/babel'>
const rootElement = document.getElementById('root')
rootElement.innerHTML = '<div>Hello World</div>'
</script>
The idea
The idea
Then why JSX ?
It seems to achieve the same goals as the older techniques
The rationale
The goal -
(The React vision, maybe)
As a template
<!-- A more sane example -->
<div id='root'></div>
<script type='text/babel'>
const rootElement = document.getElementById('root')
const name = 'Abhi'
const el = <div>Hello {name}</div>;
ReactDOM.render(el, rootElement)
</script>
As a template
As a template - composition
// We need something like this
// (Incorrect syntax below)
const Hello = <div> Hello {name} </div>;
const Score = <div> Your score is {score} </div>
const el = <div>
<Hello />
<Score />
</div>
ReactDOM.render(el, rootElement)
As a template - composition
// The following will work
const Hello = () => <div> Hello {name} </div>
const Score = () => <div> Your score is {score} </div>
const el = <div>
<Hello />
<Score />
</div>
ReactDOM.render(el, rootElement)
A function with capitalized name becomes a React component
As a template - composition
// Even better
const Hello = (props) => <div> Hello {props.name} </div>
const Score = (props) => <div> Your score is {props.value} </div>
const el = <div>
<Hello name='Abhi' />
<Score value='100' />
</div>
ReactDOM.render(el, rootElement)
All attributes passed to this component are its props
As a template - composition
// Even better
const Hello = (props) => <div> Hello {props.children} </div>
const Score = (props) => <div> Your score is {props.children} </div>
const el = <div>
<Hello> Abhi </Hello>
<Score> 100 </Score>
</div>
ReactDOM.render(el, rootElement)
All child elements within this component are its props.children
As a template - composition
// Even better
const Hello = (props) => <div> Hello {props.children} </div>
const Score = (props) => <div> Your score is {props.children} </div>
let data = { name: 'Abhi', score: 75 }
const el = <div>
<Hello> { data.name } </Hello>
<Score> { data.score } </Score>
</div>
ReactDOM.render(el, rootElement)
Externally obtained data being used here
As a template - composition
// Even better
const Hello = (props) => <div> Hello {props.children} </div>
const Score = (props) => <div> Your score is {props.children} </div>
const ScoreCard = (props) => {
<div>
<Hello> { props.name } </Hello>
<Score> { props.score } </Score>
</div>
}
let data = { name: 'Abhi', score: 75 }
let el = <ScoreCard {...data} />
ReactDOM.render(el, rootElement)
The entire widget as a component, with data passed in using spread operator
As a template - composition - summary
React.createElement
React.createElement
// JSX
var el = <div>Hello World</div>;
// Javascript
var el = React.createElement(
"div",
null,
"Hello World"
);
Try in http://babeljs.io/repl
React.createElement
// JSX
<div id='foo'>
<Hello> { props.name } </Hello>
</div>
// Javascript
React.createElement(
"div", // name in quotes
{ id: 'foo' }, // attributes
React.createElement(
Hello, // Capitalized, no quotes
null,
" ",
props.name,
" "
)
);
JSX conditionals
// Conditionals in JSX
// The following does not work
let list = [];
<div>
{
if (list.length == 0){
<div> No items </div>
}
else {
<div> {list.length} items </div>
}
}
</div>
JSX conditionals
// Conditionals in JSX
// The following works
let list = [];
<div>
{
(list.length == 0) ?
<div> No items </div>
:
<div> {list.length} items </div>
}
</div>
JSX conditionals
// Conditionals in JSX
// The following works
const render = (list ) => {
let none = <div> No Items</div>
let itemList = <div> Items list </div>
if (list.length == 0) return none;
return itemList;
}
JSX conditionals
// Conditionals in JSX
// The following works
let None = () => <div> No Items</div>
let ItemList = () => <div> Items list </div>
const render = (list ) => {
if (list.length == 0) return <None/>;
return <ItemList />;
}
JSX loops
// Loops in JSX
// The following does not work -
<div>
{
for (var i=0; i < numrows; i++) {
<span> Item - {i}</span>
}
}
</div>
JSX loops
// Loops in JSX
// The following works -
<div>
{ list.map( item => <span>Item - {item} </span> ) }
</div>
JSX loops
// Loops in JSX
// The following works -
const render = () => {
var rows = [];
for (var i = 0; i < numrows; i++) {
rows.push(<span key={i}>Item - {i} </span>);
}
return (<div>{rows}</div>);
}
JSX outside React
React Virtual DOM