<h2>Understanding JSX</h2>
<p>
This is an HTML page with a single babel-transpiled JS file and no dependencies.
It is rendering DOM via JSX without any frameworks.
</p>
body {
padding: 20px 20px 320px;
}
* {
box-sizing: border-box;
}
pre {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
max-height: 300px;
padding: 10px;
margin: 0;
background: #F3F3F3;
border-top: 1px solid #CCC;
box-shadow: inset 0 1px 10px rgba(0,0,0,0.2);
font: 11px/1.1 Menlo,Monaco,'Courier New',courier;
color: #555;
overflow: auto;
}
View Compiled
/** @jsx h */
// ^^^^ this tells a transpiler to inject calls to an `h()` function for each node.
const ITEMS = 'hello there people'.split(' ');
// a "partial" that does a filtered loop - no template BS, just functional programming:
function foo(items) {
// imagine templates that adhere to your JS styleguide...
return items.map( p => <li> {p} </li> ); // <-- can be multiline
}
// a simple JSX "view" with a call out ("partial") to generate a list from an Array:
let vdom = (
<div id="foo">
<p>Look, a simple JSX DOM renderer!</p>
<ul>{ foo(ITEMS) }</ul>
</div>
);
// render() converts our "virtual DOM" (see below) to a real DOM tree:
let dom = render(vdom);
// append the new nodes somewhere:
document.body.appendChild(dom);
// Remember that "virtual DOM"? It's just JSON - each "VNode" is an object with 3 properties.
let json = JSON.stringify(vdom, null, ' ');
// The whole process (JSX -> VDOM -> DOM) in one step:
document.body.appendChild(
render( <pre>{ json }</pre> )
);
/** Render Virtual DOM to the real DOM */
function render(vnode) {
if (typeof vnode==='string') return document.createTextNode(vnode);
let n = document.createElement(vnode.nodeName);
Object.keys(vnode.attributes || {}).forEach( k => n.setAttribute(k, vnode.attributes[k]) );
(vnode.children || []).forEach( c => n.appendChild(render(c)) );
return n;
}
/** hyperscript generator, gets called by transpiled JSX */
function h(nodeName, attributes, args) {
let children = args.length ? [].concat(args) : null;
return { nodeName, attributes, children };
}
/*
// here's an alternative hyperscript-to-vdom method that creates sparse nodes:
function h(nodeName, attributes, ...args) {
let vnode = { nodeName };
if (attributes) vnode.attributes = attributes;
if (args.length) vnode.children = [].concat(...args);
return vnode;
}
*/
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.