I’m new to React and front end in general, so I’m learning everything from square zero and I’ve hit a barrier I can’t solve by myself. What I’m trying to do now is to redirect after submitting a form. I’m using react-router-dom v.6.9.0 and most of the information I find is from previous versions which has not worked with the way I’ve structured my code. My files look as follow:
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>
);
Without the useNavigate line in form.jsx the post request works perfectly fine. However when I try to redirect using useNavigate it returns the following error:
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"
I’m not sure how to modify my files to make it work. I’ve been trying to implement other solutions from stackoverflow without much success. Could you please guide me on understanding how to redirect using a function that’s not a React component or a custom hook?
I’m using express on the backend but I don’t think that is much relevant in this problem.
2
Answers
I have two ideas here.
You shouldn’t be calling your main component function inside of itself.
Like what you do here:
React hooks can only be called from React function components or custom React hooks. You’ll need to move the
useNavigate
hook out of the callback, and move both theuseNavigate
hook and callback into the React function component.If you are trying to define the submit function externally for code-reuse then refactor it a bit to consume a passed
navigate
function.