如何在react router dom中的单个路由中使用多个操作?

问题描述 投票:0回答:2

我有两种不同组件的表单。我正在另一个组件中显示结果。我正在使用

<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
错误。

我尝试在谷歌中搜索反应路由器路由中的多个操作。但是,它只展示了如何为一个组件设置多个路由。

reactjs react-router
2个回答
6
投票

您只能执行一个操作。单个操作应该获取额外的数据,以便它可以有条件地应用一种或另一种操作逻辑。一种方法是附加一个隐藏的 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>

...

Edit how-to-use-multiple-actions-in-a-single-route-in-react-router-dom


0
投票

您可以使用按钮上的名称和值,并在提交时使用它们来区分。

    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>
  );
© www.soinside.com 2019 - 2024. All rights reserved.