我有两种不同组件的表单。我正在另一个组件中显示结果。我正在使用
<Form>
中的 react-router-dom
。并使用 action
获取数据。如果我采取一项行动,效果很好。所以我尝试添加一个额外的action
,比如,
{
path: '/show-result`,
element: <ShowResult />,
action: actionFromFirstComponent,
action: actionFromSecondComponent
}
它没有按预期工作。我也尝试过
action: [actionFromFirstComponent, actionFromSecondComponent]
。但是 react-router-dom
给我带来了 handler is not a function
错误。
我尝试在谷歌中搜索反应路由器路由中的多个操作。但是,它只展示了如何为一个组件设置多个路由。
您只能执行一个操作。单个操作应该获取额外的数据,以便它可以有条件地应用一种或另一种操作逻辑。一种方法是附加一个隐藏的 id 字段,该字段将在提交表单时与
formData
一起提交。该操作应读取此字段值并有条件地应用正确的操作逻辑。
示例:
const multiFormAction = async (actionArg) => {
const formData = await actionArg.request.formData();
const formId = formData.get("form-id");
switch (formId) {
case "form 1":
// This is form 1 logic
return actionFromFirstComponent(actionArg); // <-- pass action arg through
case "form 2":
// This is form 2 logic
return actionFromSecondComponent(actionArg); // <-- pass action arg through
default:
// Form was submitted without an id
// What to do... throw or return error? Ignore? You decide.
}
};
{
path: '/show-result`,
element: <ShowResult />,
action: multiFormAction,
}
...
<Form method="post">
<input name="form-id" hidden defaultValue="form 1" />
...
<button type="submit">Submit</button>
</Form>
...
<Form method="post">
<input name="form-id" hidden defaultValue="form 2" />
...
<button type="submit">Submit</button>
</Form>
...
async function action({ request }) {
let formData = await request.formData();
let intent = formData.get("intent");
if (intent === "edit") {
await editSong(formData);
return { ok: true };
}
if (intent === "add") {
await addSong(formData);
return { ok: true };
}
throw json(
{ message: "Invalid intent" },
{ status: 400 }
);
}
function Component() {
let song = useLoaderData();
// When the song exists, show an edit form
if (song) {
return (
<Form method="post">
<p>Edit song lyrics:</p>
{/* Edit song inputs */}
<button type="submit" name="intent" value="edit">
Edit
</button>
</Form>
);
}
// Otherwise show a form to add a new song
return (
<Form method="post">
<p>Add new lyrics:</p>
{/* Add song inputs */}
<button type="submit" name="intent" value="add">
Add
</button>
</Form>
);