View template / Server-side rendering
React CSR
const React = require('react');
const {createRoot} = require('react-dom/client');
const App = () => {
const [value, setValue] = React.useState(0);
return (
<button onClick={() => setValue(value + 1)}>
👍<sup>{value}</sup>
</button>
);
};
createRoot(document.getElementById("app")).render(<App />);
ReactDOM .createRoot
React template
const App = () => { const [value, setValue] = React.useState(0); return ( <button style={{ fontSize: 96 }} onClick={() => setValue(value + 1)}> 👍<sup>{value}</sup> </button> ); }; new Koa() .use(async (ctx) => { ctx.body = ` <div id="app">${ReactDOMServer.renderToString(<App />)}</div> `; }) .listen();
const App = () => { const [value, setValue] = React.useState(0); return <button style={{fontSize: 96}} onClick={() => setValue(value + 1)}>👍<sup>{value}</sup></button>; }; new Koa() .use(async ctx => { ctx.body = ` <script src="https://unpkg.com/react/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script> <div id="app">${ReactDOMServer.renderToString(<App />)}</div> `; }) .listen();
ReactDOM
.createRoot
.hydrateRoot
React SSR
const App = () => { const [value, setValue] = React.useState(0); return React.createElement( 'button', { style: { fontSize: 96 }, onClick: () => setValue(value + 1) }, '👍', React.createElement('sup', null, value) ); }; new Koa() .use(async (ctx) => { ctx.body = ` <div id="app">${ReactDOMServer.renderToString(<App />)}</div> <script type="module"> import React from "https://esm.sh/react"; import { hydrateRoot } from "https://esm.sh/react-dom/client"; hydrateRoot(document.getElementById("app"), React.createElement(${App})); </script> `; }) .listen();
SSR vs CSR
Next.js
npx create-next-app
getServerSideProps
import React from 'react';
export async function getServerSideProps() {
return {
props: { votes: 10 },
}
}
export default (props) => {
const [value, setValue] = React.useState(props.votes);
return (
<button style={{fontSize: 96}} onClick={() => setValue(value + 1)}>
👍<sup>{value}</sup>
</button>
);
};
File-system based router
/*
pages
├── index.js /
└── blog
├── index.js /blog
└── [id].js /blog/123
*/
import Link from 'next/link';
<Link href="/blog/hello-world">
API Routes
/*
pages
└── api
└── hello
└── [name].js /api/hello/colder
*/
export default function handler(req, res) {
const { name } = req.query
res.end('Hello ' + name);
}
Other features
Astro
npm create astro
pages/index.astro
---
import Button from './Button.astro';
import pokemon from '../data/pokemon.json';
import Home from '../components/Home.jsx';
---
<div>
<Button title="Button 1" />
<ul>
{pokemon.map(({ name }) => <li>{name}</li>)}
</ul>
<!-- 100% HTML, Zero JavaScript loaded on the page! -->
<Home />
</div>
<script is:inline>
grecaptcha.ready(() => {
grecaptcha.execute({RECAPTCHA_KEY});
});
</script>
Islands Architecture
---
import Header from '../components/Header.jsx';
import Sidebar from '../components/Sidebar.jsx';
import Carousel from '../components/Carousel.vue';
import Footer from '../components/Footer.svelte';
---
<div>
<Header client:load />
<Sidebar client:load />
<Carousel client:only="vue" />
<Footer client:visible />
</div>
fetch() in Astro
---
import Profile from '../components/Profile.jsx';
const res = await fetch('https://randomuser.me/api/');
const data = await res.json();
const user = data.results[0];
---
<div>
<h2>{user.name.first} {user.name.last}</h2>
<Profile client:load user={user} />
</div>
fetch() in React Component
const res = await fetch('https://randomuser.me/api/');
const data = await res.json();
const user = data.results[0];
console.log(user);
export const Profile = () => {
return (
<h2>{user.name.first} {user.name.last}</h2>
);
};
File-system based router
/*
pages
├── index.astro /
└── blog
├── index.astro /blog
└── [id].astro /blog/123
*/
<a href="/blog/hello-world">
Endpoints
/*
pages
├── data.js /data
└── favicon.png.ts /favicon.png
*/
export async function get({params, request}) {
return {
body: JSON.stringify({
name: 'Astro',
url: 'https://astro.build/',
}),
};
}
Qwik
npm create qwik
服务端渲染 html + js(1kb)
Serialization
import { component$ } from '@builder.io/qwik';
export const data = Promise.resolve('data');
export const Demo = component$(() => {
console.log(topLevel);
return (
<button onClick$={() => {
console.log(topLevel);
}} />
);
});
Thank you