Skip to content

Latest commit

 

History

History
153 lines (114 loc) · 3.79 KB

README.md

File metadata and controls

153 lines (114 loc) · 3.79 KB

Reactem

NPM NPM NPM

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.

Installation

yarn add @gsail/reactem

OR

npm install --save @gsail/reactem


Usage

// 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>

Usage of async/await & Context API

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>