Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/aduh95/async-jsx
JSX syntax for vanilla JS, and async
https://github.com/aduh95/async-jsx
Last synced: 1 day ago
JSON representation
JSX syntax for vanilla JS, and async
- Host: GitHub
- URL: https://github.com/aduh95/async-jsx
- Owner: aduh95
- License: mit
- Created: 2019-09-15T14:55:01.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2023-08-23T09:48:54.000Z (about 1 year ago)
- Last Synced: 2024-09-28T18:48:21.330Z (5 days ago)
- Language: TypeScript
- Size: 27.3 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.MD
- License: LICENSE
Awesome Lists containing this project
README
# Async-JSX
This package aims to give you the opportunity to use the JSX syntax introduced
by React, without using React at all.Key differences with React API:
- No VirtualDOM (less overhead, but also less reactivity)
- Everything is asynchronous
- No Component life-cycle## Usage
### Get Started
```js
import { h } from "@aduh95/async-jsx";const element =
Hello World;console.log(element instanceof Promise); // true
element.then((domElement) => console.log(domElement instanceof HTMLElement)); // true
document.body.append(renderAsync(element));
```It is recommended to add this CSS to your page to avoid custom elements leaking
into your design:```css
async-component,
conditional-element {
display: contents;
}
dom-portal {
display: none;
}
```### Build tools
#### With Babel
You can use the `@babel/plugin-transform-react-jsx` package:
```json
{
"plugins": [
[
"@babel/plugin-transform-react-jsx",
{ "pragma": "h", "pragmaFrag": "Fragment" }
]
]
}
```#### With TypeScript
In the `tsconfig.json`:
```json
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "h"
}
}
```### With dynamic imports
You can define a component in a separate file and lazy-load it:
```js
/* Greetings.js */
import { h } from "@aduh95/async-jsx";// You can use an arrow function instead of a class
export default (props) => (
Hello {props.name}
);
``````js
/* App.js */
import {
h,
lazy,
Component,
Fragment,
conditionalRendering,
} from "@aduh95/async-jsx";
const Greetings = lazy(() => import("./Greetings.js"));export default class App extends Component {
stateObservers = new Set();
greetingName = "";_handleNewName = this.handleNewName.bind(this);
handleNewName(ev) {
const { target } = ev;
this.greetingName = target.value;
this.stateObservers.forEach((fn) => fn("ready"));
}render() {
return (
<>
Welcome
{conditionalRendering(
{
ready: ,
askForName: (
),
},
this.stateObservers,
ready,
console.error
)}
>
);
}
}
```### StatefulComponent
I have added a React-compatible `StatefulComponent`, which can be used the same
way as a `React.Component`. However, because of the lack of VirtualDOM, it can
be highly inefficient to use it. For example, let's take the Clock example from
React docs:```js
import { h, StatefulComponent } from "@aduh95/async-jsx";
class Clock extends StatefulComponent {
constructor(props) {
super(props);
this.state = { date: new Date() };
}componentDidMount() {
this.timerID = setInterval(() => this.tick(), 1000);
}componentWillUnmount() {
clearInterval(this.timerID);
}tick() {
this.setState({
date: new Date(),
});
}render() {
return (
Hello, world!
It is {this.state.date.toLocaleTimeString()}.
);
}
}document
.getElementById("root")
.append(renderAsync(, null, console.error));
```This will work apparently, but at each tick, 3 DOM elements are initiated. Perf
difference may not be visible on that small example, but you can imagine that
having a whole site re-render every time something change will put a lot of
pressure on small-CPU clients.### SVG Elements
Because SVG Elements cannot be created using `Document.prototype.createElement`,
but by `Document.prototype.createElementNS`, they cannot be created by the usual
`h` p(or `createElement`) function. pIf you want to create SVG elements using
JSX, you can put them in a separate module:```js
// Logo.js
import { createSVGElement as h } from "../utils/jsx.js";export default () => (
);
```Then you can import this module in another component:
```js
import { Component, h } from "../utils/jsx.js";
import Logo from "./Logo.js";export default class Header extends Component {
render() {
return (
Title
);
}
}
```## API
This repo is using TypeScript, you can use it to have access to the
documentation during development. The API is defined by the `.d.ts` files.