Nextjs 服务器操作问题
形式为:
type Ingredient = {
name: string;
purchasePrice: Prisma.Decimal;
}
const onSubmit = async (values: Ingredient) => {
await addIngredient(values)
}
在成分-actions.ts 文件中:
export const addIngredient = async (ingredientData: Ingredient ): Promise<IngredientPrisma | ErrorMessage> => {
try {
const ingredientResponse = await prisma.ingredient.create({ data: {
name: ingredientData.name,
purchasePrice: ingredientData.purchasePrice,
} });
revalidatePath('/dashboard');
return ingredientResponse;
} catch (err) {
return {
message: 'Error creating ingredient'
}
}
}
我遇到错误(“只有普通对象可以传递给服务器函数”),
所以同时我正在通过addIngredient(JSON.stringify(values))
在onSubmit
. 并在操作的定义中,通过执行撤消JSON.parse(ingredientData)
。
export const addIngredient = async (ingredientData: string): Promise<IngredientPrisma | ErrorMessage> => {
try {
const ingredient:Ingredient = JSON.parse(ingredientData);
const ingredientResponse = await prisma.ingredient.create({ data: {
name: ingredient.name,
purchasePrice: ingredient.purchasePrice,
} });
revalidatePath('/dashboard');
return ingredientResponse;
} catch (err) {
return {
message: 'Error creating ingredient'
}
}
}
如果不使用 JSON 你会如何处理这个问题?
为什么会出现这种情况?
正如错误所示,允许使用普通对象,而无需先将其转换为 JSON 字符串。这意味着不允许使用函数之类的东西(因为函数无法序列化并发送到服务器)。然而a
Prisma.Decimal
不是普通对象,也不是数组,也不是基元(如字符串、数字或布尔值)。查看Prisma 文档,我们发现:
该库构造“类”(用引号引起来,因为 JS 从技术上讲没有类,它们只是基于原型的继承的语法糖)实例,这些实例可以(在 Decimal.js 的情况下)具有无法序列化的实例函数。
我们用它做什么?
首先,我不确定这是编译器/linter 警告还是实际的运行时警告。无论它是否是编译器/linter 警告,将 的类型更改
Ingredient
为以下就足够了:这也应该更准确,因为您的前端不应该有 Prisma 的“概念”。
Next.js 中前端和后端之间的界限非常模糊,但由于服务器操作是从前端调用的,所以这部分代码应该只关心纯数据,而不是 ORM 然后处理它的特定“表示”。在将其存储到数据库之前,您仍然可以将其转换为 Prisma.Decimal。