
在 Remix 中,useSubmit() 支持直接提交 JavaScript 对象(如 { id, product, order }),只需将 encType 设为 "application/json",并在 action 中调用 request.json() 解析,无需手动 JSON.stringify() 和 JSON.parse()。
在 remix 中,`usesubmit()` 支持直接提交 javascript 对象(如 `{ id, product, order }`),只需将 `enctype` 设为 `"application/json"`,并在 action 中调用 `request.json()` 解析,无需手动 `json.stringify()` 和 `json.parse()`。
Remix 的 useSubmit() Hook 不仅支持传统的 multipart/form-data 表单提交,也原生支持标准 JSON 提交——这是自 Remix v2 起强化的推荐方式,语义更清晰、类型更安全、开发体验更接近现代 API 实践。
✅ 推荐写法(简洁、类型友好、无需序列化):
const onSubmit = () => {
const updatedContact = { name: "John Doe", email: "" };
const updatedOrder = {
products: [
{ id: 1, name: "Product 1", quantity: 1 },
{ id: 2, name: "Product 2", quantity: 2 },
],
total: 100,
};
// 直接传入普通对象,指定 JSON 编码
submit(
{ id, product: updatedContact, order: updatedOrder },
{ method: "post", encType: "application/json" }
);
};
对应的服务端 action 可直接解构解析:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
export const action: ActionFunction = async ({ request }) => {
const { id, product, order } = await request.json(); // ✅ 自动解析为 JS 对象
console.log({ id, product, order });
// { id: "123", product: { name: "John Doe", email: "" }, ... }
// 后续业务逻辑(如数据库保存、验证等)
return json({ success: true });
};
⚠️ 注意事项:
-
encType: "application/json"是关键;若误写为"multipart/form-data"或"application/x-www-form-urlencoded",则request.json()会抛出解析错误。 - 确保前端提交的对象是可序列化的(不含
undefined、函数、Date对象等;如需传递日期,建议转为 ISO 字符串)。 - Remix 官方文档明确指出:当
encType为"application/json"时,submit()会自动调用JSON.stringify()并设置正确的Content-Type头,开发者无需手动处理。 - 若需文件上传,则仍需使用
FormData+multipart/form-data,此时 JSON 序列化才是必要步骤。
? 小结:
放弃手动 JSON.stringify() / JSON.parse() 的“胶水代码”,拥抱 encType: "application/json" + request.json() 的直连模式——它更符合 RESTful 语义、减少出错点、提升 TypeScript 类型推导准确性,也是 Remix 团队当前大力倡导的最佳实践。










