Skip to content

Commit 7d38756

Browse files
committed
Add react streaming api
1 parent b01cf22 commit 7d38756

File tree

2 files changed

+29
-24
lines changed

2 files changed

+29
-24
lines changed

src/browser.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import * as ReactDOM from 'react-dom';
2+
import { hydrate } from 'react-dom';
33
import App from './components/app';
44
import { propsUrl, containerId } from './constants';
55

@@ -8,5 +8,6 @@ fetch(propsUrl)
88
.then((props: AppProps) => {
99
const app = (<App {...props} />);
1010
const el = document.getElementById(containerId);
11-
ReactDOM.hydrate(app, el);
11+
const h = hydrate as any;
12+
h(app, el);
1213
});

src/server.tsx

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createServer } from 'http';
2-
import * as React from 'react';
3-
import { renderToString } from 'react-dom/server';
2+
import { createFactory } from 'react';
3+
import { renderToNodeStream } from 'react-dom/server';
44
import { readFile } from 'fs';
55
import { promisify } from 'util';
66
import AppComponent from './components/app';
@@ -10,7 +10,7 @@ import { faviconUrl, stylesUrl, reactUrl, reactDomUrl, browserUrl, browserMapUrl
1010
console.log('Server booting...');
1111
const isProd = process.env.NODE_ENV === 'production';
1212
console.log('Production optimization enabled? ', isProd);
13-
const App = React.createFactory(AppComponent);
13+
const App = createFactory(AppComponent);
1414
const PORT = process.env.PORT || 3007;
1515
const suffix = isProd ? '.production.min.js' : '.development.js';
1616
const readFileAsync = promisify(readFile);
@@ -19,26 +19,30 @@ createServer(async (req, res) => {
1919
const { httpVersion, method, url } = req;
2020
console.log(`${httpVersion} ${method} ${url}`);
2121
if (url === '/') {
22-
const props: AppProps = { items: getItems() };
23-
const reactHtml = renderToString(App(props));
24-
const pageHtml = `<!DOCTYPE html>
25-
<html>
26-
<head>
27-
<meta charset="utf-8" />
28-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
29-
<link href="${faviconUrl}" rel="icon" type="image/x-icon" />
30-
<title>React Example</title>
31-
<link rel="stylesheet" href="${stylesUrl}" />
32-
</head>
33-
<body>
34-
<div id="${containerId}">${reactHtml}</div>
35-
<script src="${reactUrl}"></script>
36-
<script src="${reactDomUrl}"></script>
37-
<script src="${browserUrl}"></script>
38-
</body>
39-
</html>`;
22+
4023
res.setHeader('Content-Type', 'text/html');
41-
res.end(pageHtml)
24+
res.write('<!DOCTYPE html>');
25+
res.write(`<html>
26+
<head>
27+
<meta charset="utf-8" />
28+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
29+
<link href="${faviconUrl}" rel="icon" type="image/x-icon" />
30+
<title>React Example</title>
31+
<link rel="stylesheet" href="${stylesUrl}" />
32+
</head>
33+
<body>
34+
<div id="${containerId}">`);
35+
const props: AppProps = { items: getItems() };
36+
const stream = renderToNodeStream(App(props)) as any;
37+
stream.pipe(res, { end: false });
38+
stream.on('end', () => {
39+
res.end(`</div>
40+
<script src="${reactUrl}"></script>
41+
<script src="${reactDomUrl}"></script>
42+
<script src="${browserUrl}"></script>
43+
</body>
44+
</html>`);
45+
});
4246
} else if (url === propsUrl) {
4347
const items = getItems();
4448
const props = {items: items};

0 commit comments

Comments
 (0)