提问人:Sandy 提问时间:10/23/2023 最后编辑:Sandy 更新时间:10/28/2023 访问量:118
如何在 NextJS 服务器操作中使用 renderToStaticMarkup
How to use renderToStaticMarkup in NextJS server action
问:
我正在尝试在 NextJS 13 服务器操作中使用以通过电子邮件发送生成的 HTML。renderToStaticMarkup
import { renderToStaticMarkup } from "react-dom/server";
import { sendEmail } from "@/infra/email";
import { ResetPasswordEmail } from "@/infra/email/templates";
import { userRoutes } from "@/routes";
interface SendPasswordResetLink {
email: string;
firstName: string;
passwordResetToken: string;
}
export const sendPasswordResetLink = async ({ email, firstName, passwordResetToken }: SendPasswordResetLink): Promise<void> => {
const url = userRoutes.resetPassword.generateUrl(passwordResetToken);
const subject = `Password reset`;
const html = renderToStaticMarkup(<ResetPasswordEmail firstName={firstName} url={url} />);
const result = await sendEmail({ html, subject, toEmail: email, toName: firstName });
//... more code
};
但是,我在后端收到以下错误:Error: × Expected '>', got 'firstName'
在 VSCode 中,我得到红色的波浪线,当我悬停时,它说:'ResetPasswordEmail' refers to a value, but is being used as a type here. Did you mean 'typeof ResetPasswordEmail'?ts(2749)
该组件没有任何交互性,其文件名以 结尾。ResetPasswordEmail
.tsx
知道如何解决这个问题,或者以其他方式在服务器操作中发送HTML电子邮件吗?谢谢!
答:
该错误可能是由于 nodejs 无法识别 JSX 语法引起的。尝试改用 React.createElement。
const element = React.createElement(ResetPasswordEmail, {firstName, url})
const html = renderToStaticMarkup(element)
建议:
由于您使用 NextJS 进行 SSR,也许最好让 NextJS 处理渲染,然后您可以向 NextJS 服务器发出请求以获取渲染的 HTML 并通过电子邮件发送。
您看到的错误可能是由于 TypeScript 类型错误造成的。
当您在函数中使用组件时,TypeScript 会将其视为值而不是类型。<ResetPasswordEmail>
renderToStaticMarkup
要修复此错误,您可以尝试使用 typeof 关键字将组件导入为类型。ResetPasswordEmail
下面是一个示例:
import { renderToStaticMarkup } from "react-dom/server";
import { sendEmail } from "@/infra/email";
import { ResetPasswordEmail } from "@/infra/email/templates";
import { userRoutes } from "@/routes";
interface SendPasswordResetLink {
email: string;
firstName: string;
passwordResetToken: string;
}
export const sendPasswordResetLink = async ({ email, firstName, passwordResetToken }: SendPasswordResetLink): Promise<void> => {
const url = userRoutes.resetPassword.generateUrl(passwordResetToken);
const subject = `Password reset`;
const html = renderToStaticMarkup(<typeof ResetPasswordEmail>{ firstName, url });
const result = await sendEmail({ html, subject, toEmail: email, toName: firstName });
//... more code
};
此示例使用 typeof 关键字将组件导入为类型。还使用对象速记符号将 and props 直接传递给组件。ResetPasswordEmail
firstName
url
您也可以尝试使用该函数代替 . 是一个服务器端呈现函数,旨在与 Next.js 一起使用。renderToString
renderToStaticMarkup
renderToString
这是:
import { renderToString } from "react-dom/server";
import { sendEmail } from "@/infra/email";
import { ResetPasswordEmail } from "@/infra/email/templates";
import { userRoutes } from "@/routes";
interface SendPasswordResetLink {
email: string;
firstName: string;
passwordResetToken: string;
}
export const sendPasswordResetLink = async ({ email, firstName, passwordResetToken }: SendPasswordResetLink): Promise<void> => {
const url = userRoutes.resetPassword.generateUrl(passwordResetToken);
const subject = `Password reset`;
const html = renderToString(<ResetPasswordEmail firstName={firstName} url={url} />);
const result = await sendEmail({ html, subject, toEmail: email, toName: firstName });
//... more code
};
在此示例中,使用该函数将组件呈现为字符串。还使用对象速记符号将 and props 直接传递给组件。renderToString
ResetPasswordEmail
firstName
url
评论
sendPasswordResetLink
.ts
.tsx