javascript 如何使用react router v.6.9.0 + react-hook-form提交表单后重定向?

e0uiprwp  于 2023-03-28  发布在  Java
关注(0)|答案(2)|浏览(126)

我是React和前端的新手,所以我从零开始学习,我遇到了一个我自己无法解决的障碍。我现在尝试做的是在提交表单后重定向。我使用react-router-dom v.6.9.0,我发现的大部分信息来自以前的版本,这些版本与我的代码结构不匹配。我的文件如下:
form.jsx

import React from 'react';
import { useForm } from 'react-hook-form';
import {useState} from 'react';
import { redirect, useNavigate } from 'react-router-dom';

function onSubmit(data){
    const navigate = useNavigate();
    alert(JSON.stringify(data, null, 4));
    fetch("/api/submitHo", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body:JSON.stringify(data)
    }).then(
        response => response.json()
    ).then(
        res => {
            console.log(res);
            navigate("/");})
}

*/.../*

function TheForm() {
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm();
  
*/.../*

  return (
    <React.Fragment>
        <form onSubmit={handleSubmit((data) =>onSubmit(data))}>
           */.../* 
        </form>
    </React.Fragment>
  );
}

export default TheForm

root.jsx

import { Outlet, Link } from "react-router-dom";

export default function Root() {
  return (
    <>
      <div id="sidebar">
        <nav>
          <ul>
          <li>
              <Link to={`/new-form`}>NEW HO Input</Link>
            </li>
            <li>
              <Link to={`/ho-viewer`}>HO Viewer</Link>
            </li>
          </ul>
        </nav>
      </div>
            <div id="detail">
        <Outlet />
      </div>
    </>
  );
}

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";
import "./index.css";
import ErrorPage from "./errorPage";
import HoViewer from "./routes/hoViewer";
import Root from "./routes/root";
import TheForm from "./routes/form";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    children: [
      {
        path: "/ho-viewer",
        element: <HoViewer/>,
        errorElement: <ErrorPage />,
      },
      {
        path: "/new-form",
        element: <TheForm />,
        errorElement: <ErrorPage />,
      },
    ],
  },

]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

如果form.jsx中没有useNavigate行,post请求工作得很好。但是,当我尝试使用useNavigate重定向时,它返回以下错误:
React Hook "useNavigate" is called in function "onSubmit" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use"
我不知道如何修改我的文件来使其工作。我一直在尝试从stackoverflow实现其他解决方案,但没有太大的成功。你能指导我理解如何使用非React组件或自定义钩子的函数进行重定向吗?
我在后端使用express,但我不认为这与这个问题有多大关系。

sr4lhrrt

sr4lhrrt1#

我有两个想法。
1.将useNavigate的声明移到函数的外部。因此它看起来像这样:

import React from 'react';
import { useForm } from 'react-hook-form';
import {useState} from 'react';
import { redirect, useNavigate } from 'react-router-dom';

export default MyReactComponent(){
 const navigate = useNavigate();

function onSubmit(data){
    alert(JSON.stringify(data, null, 4));
    fetch("/api/submitHo", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body:JSON.stringify(data)
    }).then(
        response => response.json()
    ).then(
        res => {
            console.log(res);
            navigate("/");})
}
}

你不应该在主组件函数内部调用它。就像你在这里做的:

return (
    <React.Fragment>
        <form onSubmit={handleSubmit((data) =>onSubmit(data))}>
           */.../* 
        </form>
    </React.Fragment>
);

1.你可以通过创建一个返回主页函数并调用它来尝试使用重定向,而不是useNavigate:

import React from 'react';
import { useForm } from 'react-hook-form';
import {useState} from 'react';
import { redirect, useNavigate } from 'react-router-dom';

function returnHome(){
return redirect("/");
}

function onSubmit(data){
    const navigate = useNavigate();
    alert(JSON.stringify(data, null, 4));
    fetch("/api/submitHo", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body:JSON.stringify(data)
    }).then(
        response => response.json()
    ).then(
        res => {
            console.log(res);
            returnHome();})
}
kadbb459

kadbb4592#

React hook只能从React函数组件或自定义React hook调用。您需要将useNavigate hook***移出***回调,并将useNavigate hook和回调***移入***React函数组件。

import React from 'react';
import { useForm } from 'react-hook-form';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';

...

function TheForm() {
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm();

  const navigate = useNavigate();

  function onSubmit(data) {
    alert(JSON.stringify(data, null, 4));
    fetch("/api/submitHo", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify(data)
    })
      .then(response => response.json())
      .then(res => {
        console.log(res);
        navigate("/");
      });
  }
  
  ...

  return (
    <React.Fragment>
      <form onSubmit={handleSubmit(onSubmit)}>
        */.../* 
      </form>
    </React.Fragment>
  );
}

export default TheForm;

如果您试图在外部定义submit函数以实现代码重用,则需要对其进行一点重构,以使用传递的navigate函数。

import React from 'react';
import { useForm } from 'react-hook-form';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';

const onSubmit = (navigate) => (data) => {
  alert(JSON.stringify(data, null, 4));
  fetch("/api/submitHo", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify(data)
  })
    .then(response => response.json())
    .then(res => {
      console.log(res);
      navigate("/");
    });
};

...

function TheForm() {
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm();
  
  const navigate = useNavigate();

  ...

  return (
    <React.Fragment>
        <form onSubmit={handleSubmit(onSubmit(navigate))}>
           */.../* 
        </form>
    </React.Fragment>
  );
}

export default TheForm;

相关问题