A template engine to generate html on server which you can write in JSX and use React.useContext API
This framework is inspired by vhtml and React. I want to use JSX to render HTML on the server side, but I don't want to use React. It is static HTML, VDOM is not necessary.
Then I found vhtml, a light framework that Render JSX/Hyperscript to HTML strings, without VDOM.
But I needed some asynchronous operations and Context, so I developed this Reactem (React + Template).
In some less rigorous test situations, it is 3 times faster than React
Reactem is currently just a toy. It is not perfect and there may be bugs. Feedback and issues are welcome.
yarn add @gsail/reactem
OR
npm install --save @gsail/reactem
// import the library:
import Reactem, { renderToString } from '@gsail/reactem'
// you might need @babel/plugin-transform-react-jsx
// tell babel to transpile JSX to h() calls:
/** @jsx Reactem.h */
/** @jsxFrag Reactem.Fragment */
// OR /** @jsx Reactem.createElement */
// Write some simple functional components, just like in React
const Item = ({ item, index, children }) => (
<li id={index}>
<h4>{item}</h4>
{children}
</li>
);
const App = ()=>{
let items = ['book', 'card', 'notebook'];
return (
<div class="foo">
<h1>Hello World!</h1>
<p>Here is a list of {items.length} items:</p>
<ul>
{ items.map( (item, index) =>
<Item {...{ item, index }}>
This is : {item}!
</Item> )}
</ul>
</div>
)
}
// Then render it to get the html string
console.log(renderToString(<App>));
The HTML you get:
<div class="foo">
<h1>Hello World!</h1>
<p>Here is a list of 3 items:</p>
<ul>
<li id="0">
<h4>book</h4>This is : book!
</li>
<li id="1">
<h4>card</h4>This is : card!
</li>
<li id="2">
<h4>notebook</h4>This is : notebook!
</li>
</ul>
</div>
import Reactem, { createContext, useContext, renderToStringAsync } from '@gsail/reactem'
/** @jsx Reactem.h */
/** @jsxFrag Reactem.Fragment */
const CTX = createContext({v: 0})
let sleep = (time) => new Promise(reslove => {
setTimeout(() => reslove(time), time * 1000)
})
let B = () => {
let ctx = useContext(CTX)
return (<div>
B.ctx.v:{ctx.v}
</div>)
};
let C = async () => {
let time = await sleep(1)
let ctx = useContext(CTX)
return (<div className='con'>
Time:{time} C.ctx.v:{ctx.v}
<CTX.Provider value={{v:2}}>
<B/>
</CTX.Provider>
<B/>
</div>)
};
let App = ()=>{
return <>
<style dangerouslySetInnerHTML={{__html:'.con{color:red}'}}/>
<CTX.Provider value={{v:9}}>
<C/>
</CTX.Provider>
<B/>
</>
};
(async ()=>{
console.log(await renderToStringAsync(<App>));
}())
The HTML you get:
<style>.con{color:red}</style>
<div class="con">
Time:1 C.ctx.v:9
<div>B.ctx.v:2</div>
<div>B.ctx.v:9</div>
<div>B.ctx.v:0</div>
</div>