how to res koa2 with react 18.0.0 renderToPipeableStream
gseok opened this issue · comments
gyeongseok.seo commented
- react release 18.0.0 and there are support node stream api(ssr) 'renderToPipeableStream'.
- so I'm try to using 'renderToPipeableStream' in my code But Res failed....
- plz, help me the React(18.0.0) + Koa2.... how to stream res...
// this is my code block
import { Context, Next } from 'koa';
import Router from 'koa-router';
...
const router = new Router();
const ssrTest = async (ctx: Context) => {
const { pipe } = ReactDomServer.renderToPipeableStream(
<App />,
{
onCompleteShell() {
ctx.respond = false;
ctx.res.statusCode = 200;
ctx.response.set('content-type', 'txt/html');
ctx.type = 'html';
pipe(ctx.res);
ctx.res.end();
},
},
);
}
router.get('/test', ssrTest);
Danilo Assis commented
What is the error when are trying to use the renderToPipeableStream
?
gyeongseok.seo commented
- I think my final response is stream data ( html), But Final response is my final route code (page not found)
- stream res is not wait?
...
app.use(router.routes()); // <-- code is ok but not res this code
...
app.use(finalPageNotFound); // <-- res is this code...
- renderToPipeableStream's onCompleteShell function is callback style.. so .. there are no await and pass the final route?
gyeongseok.seo commented
- change code and success..
- using promise and await
- change callback fn
onCompleteShell
toonAllReady
// this is my code block
import { Context, Next } from 'koa';
import Router from 'koa-router';
...
const router = new Router();
const sendStreamRes = async (ctx: Context) => {
const prefix = `<!DOCTYPE html><html><body><div>`;
const postfix = `</div></body></html>`;
return new Promise((_resolve, reject) => {
const { pipe } = ReactDomServer.renderToPipeableStream(
<App />,
{
onAllReady() {
ctx.respond = false;
ctx.res.statusCode = 200;
ctx.response.set('content-type', 'txt/html');
ctx.type = 'html';
ctx.res.write(prefix);
pipe(ctx.res);
ctx.res.write(postfix);
ctx.res.end();
},
onShellError() {
reject();
}
},
);
});
}
const ssrTest = async (ctx: Context) => {
await sendStreamRes(ctx);
}
router.get('/test', ssrTest);
...
Snake commented
To bypass Koa's built-in response handling, you may explicitly set ctx.respond = false;. Use this if you want to write to the raw res object instead of letting Koa handle the response for you.
Note that using this is not supported by Koa. This may break intended functionality of Koa middleware and Koa itself. Using this property is considered a hack and is only a convenience to those wishing to use traditional fn(req, res) functions and middleware within Koa.
Is there any other way without using ctx.respond? if you want streaming HTML.