JSX is an extension of JavaScript that allows interleaving XML-style code and JavaScript code. It makes describing layout based on JavaScript logic and data pretty convenient.
Browsers cannot understand JSX, you need a tool to transform it into JavaScript. Tools like TypeScript or Babel can handle that transformation, with corresponding config telling them how they should transpile JSX code.
With proper configuration, this JSX code:
1linkconst name = 'Jack';
2linkconst title = 'Greetings!';
3link
4link<div class='hellow' title={title}>Hi {name}!</div>
is transpiled to this JavaScript code:
1linkconst name = 'Jack';
2linkconst title = 'Greetings!';
3link
4linkrenderer.create('div', { class: 'hellow', title: title }, 'Hi', name, '!');
Or this JSX code:
1link<MyComponent prop={something}/>
is transpile to this:
1linkrenderer.create(MyComponent, { prop: something });
Because JSX is transpiled to renderer.create()
expressions, you MUST have an object named
renderer
, which is an actual renderer (or at least has a .create()
method), defined in the scope.
🚫 WRONG:
1linkconst div = /*~*/<div>~~~~~Hellow~~~~~~</div>~~~~~~/*~*/; // --> ERROR: renderer is not defined
2link
3linkconst renderer = makeRenderer();
4linkrenderer.render(div).on(document.body);
👌 CORRECT:
1linkconst renderer = makeRenderer();
2link
3linkconst div = <div>Hellow</div>; // --> renderer is now defined
4linkrenderer.render(div).on(document.body);
🚫 WRONG:
1linkfunction MyComponent(props) {
2link reutrn /*~*/<div>~~~~~Hellow~~~~~~</div>~~~~~~/*~*/; // --> ERROR: renderer is not defined
3link}
👌 CORRECT:
1linkfunction MyComponent(props, renderer) {
2link reutrn <div>Hellow</div>; // --> renderer is now defined
3link}
Since JSX is just a syntactic sugar, you can use callbag-jsx
without actually using JSX:
1link<div class="hellow" tabindex={2}>Hellow</div>
1linkrenderer.create('div', {class: 'hellow', tabindex: 2}, 'Hellow');
1link<Component prop={value}>Some {stuff}</Component>
1link renderer.create(Component, {prop: value}, 'Some', stuff);
1linkconst renderer = makeRenderer();
2link
3linkconst s = state(0);
4link
5linkrenderer.render(
6link <div>You were here for {s} seconds!</div>
7link).on(document.body);
8link
9linksetInterval(() => s.set(s.get() + 1), 1000);
1linkconst renderer = makeRenderer();
2link
3linkconst s = state(0);
4link
5linkrenderer.render(
6link renderer.create('div', {}, 'You were here for ', s, ' seconds!')
7link).on(document.body);
8link
9linksetInterval(() => s.set(s.get() + 1), 1000);