为什么在react router dom中调用useActionData()时不是对象解构?

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

当我调用 useActionData() 时,我没有得到任何对象销毁。当我打印到控制台时,我得到名称:“isakGo”。代码看起来像这样

export async function action({request}) {
  const formData = await request.formData();
  const name = { name: formData.get("name") }
  return { name };
}

export default function FormTest() {
  const { name } = useActionData(); // error has occured here

  // other codes
}

我们正在使用 createBrowserRouter() 创建一个路由器,并使用 RouterBrowser 为其提供服务。

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    children: [
      {
        path: "/FormTest",
        element: <FormTest />,
        action: formTestAction,
      }
    ]
  },
])

出现以下错误。

无法解构“(0,react_router_dom__WEBPACK_IMPORTED_MODULE_1__.useActionData)(...)”的属性“名称”,因为它未定义。

如果您将代码更改为不进行对象销毁的代码,它将可以正常工作。

export async function action({request}) {
  const formData = await request.formData();
  const name = { name: formData.get("name") }
  return name;
}

export default function FormTest() {
  const name = useActionData(); 

  // other codes
}

当我在react router dom中编写类似loader()的东西时,即

const { name } = useLoaderData();
,它工作得很好。 action() 不会破坏该对象。我错过了什么?

我正在使用 create-react-app 和 [email protected] 版本。

编辑

我们发现了可能与错误直接相关的其他因素。

  1. useActionData()在FormTest()加载时被调用,所以空name变量为空。
  2. 由于某种原因,当我将结果打印到控制台时,它被调用了4次。
javascript reactjs react-router-dom destructuring
2个回答
1
投票

文档

此钩子提供上一个导航操作结果的返回值,如果没有提交,则为未定义。

function SomeComponent() {
  let actionData = useActionData();
  // ...
}

此挂钩最常见的用例是表单验证错误。如果表单不正确,您可以返回错误并让用户重试:

代码示例

import {
  useActionData,
  Form,
  redirect,
} from "react-router-dom";

export default function SignUp() {
  const errors = useActionData();

  return (
    <Form method="post">
      <p>
        <input type="text" name="email" />
        {errors?.email && <span>{errors.email}</span>}
      </p>

      <p>
        <input type="text" name="password" />
        {errors?.password && <span>{errors.password}</span>}
      </p>

      <p>
        <button type="submit">Sign up</button>
      </p>
    </Form>
  );
}

export async function action({ request }) {
  const formData = await request.formData();
  const email = formData.get("email");
  const password = formData.get("password");
  const errors = {};

  // validate the fields
  if (typeof email !== "string" || !email.includes("@")) {
    errors.email =
      "That doesn't look like an email address";
  }

  if (typeof password !== "string" || password.length < 6) {
    errors.password = "Password must be > 6 characters";
  }

  // return data if we have errors
  if (Object.keys(errors).length) {
    return errors;
  }

  // otherwise create the user and redirect
  await createUser(email, password);
  return redirect("/dashboard");
}

0
投票

我不确定我的处理是否正确,但你可以尝试这个

let nameTmp;  
if (useLoaderData()) {
    const { name } = useLoaderData();
    nameTmp = name;
}

html 里面

<Await resolve={nameTmp} errorElement={<p>Error loading!</p>} >
© www.soinside.com 2019 - 2024. All rights reserved.