Never responds html via Suspense
What version of Hono are you using?
4.0.1
What runtime/platform is your app running on?
Cloudflare Workers
What steps can reproduce the bug?
const Layout2: FC = async ({ children }) => {
return await html`<div>${children}</div>`;
};
const Layout: FC = async ({ children }) => {
// return await html`<div>${Layout2({ children })}</div>`; // Will be successful
return await html`<div>${await Layout2({ children })}</div>`;
};
app
.use(
'/suspense',
jsxRenderer(
({ children }) => {
return (<Layout>{children}</Layout>);
},
{ stream: true },
),
)
.get('/suspense', async (c) => {
const AsyncComponent: FC = async () => {
await new Promise((r) => setTimeout(r, 1000)); // sleep 1s
return await (<Layout>Hello</Layout>);
};
return await c.render(
<Suspense fallback={<div>Loading...</div>}>
<AsyncComponent />
</Suspense>,
);
});
What is the expected behavior?
Render Layout2 component after finished sleep 1s
What do you see instead?
Loading...
Additional information
No response
Hi @Code-Hex
I think the await is not necessary:
return await html`<div>${await Layout2({ children })}</div>`
The above should be the following as you write:
return await html`<div>${Layout2({ children })}</div>`
Is there any reason to write await?
@yusukebe I didn't write async await code directly, written it by @typescript-eslint/promise-function-async
related: https://github.com/honojs/hono/issues/1812
This issue is a simplified version to demonstrate reproducibility. In reality, the problem occurred with the following code:
const Layout2 = async ({children}: {children:JSX.Element}) => await html`<div>${children}</div>`
<div>${Layout2({ children: await Layout3() })}</div>
Identifying the problem is difficult because lint automatically corrects it to:
const Layout2 = async ({children}: {children:JSX.Element}) => await html`<div>${children}</div>`
<div>${Layout2({ children: Layout3() })}</div> // will be changed by linter
Hi @Code-Hex
Can you adopt the work-around of writing the following?
return await html`<div>${<Layout2>{children}</Layout2>}</div>`
or
import { jsx } from 'hono/jsx'
...
return await html`<div>${jsx(Layout2, {}, children)}</div>`
@usualoma Thank you. I'm currently avoiding with a similar approach!
return await html`<div>${<Layout2>{children}</Layout2>}</div>`
@Code-Hex Thank you for your response.
I thought, "Doesn't this look better?".
return await html`<div>${<Layout2>{children}</Layout2>}</div>`
However, there may be times when it is more convenient to pass HtmlEscapedString, so I would like to support this notation in #2233.