I have a simple signup form and using react-hook-form
and react-router
. I want to redirect within onSubmit
after the Axios post request. I can't make it happen and I can't find anything online explaining why.
I have tried both redirect
and useNavigate
from react-router
. Nothing happens with redirect
and I get this error when using navigate
:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
I found a post where the maintainer of Hook-Form that suggests using props.history.push("./my-route")
as is done here in 'Step1.' But this doesn't work for me. I don't know where history is coming from. The only thing that works is window.location.replace("/my-route")
but I don't like this solution at all.
Can someone help me or explain why the react-router
methods are not working? Is it because Hook-Form is uncontrolled?
My code:
import axios from "axios";
import { useForm } from "react-hook-form";
import { redirect, useNavigate } from "react-router-dom";
export function Login() {
const onSubmit = async (data) => {
try {
console.log(data);
await axios.post("http://localhost:5000/signup", data);
// window.location.replace("/my-route");
} catch (error) {
console.error("There was an error!", error);
}
};
return (
<div>
<h1>Blah</h1>
<h4>Signup</h4>
<form key={1} onSubmit={handleSubmit(onSubmitSignup)}>
<input
{...register("email", { required: true, minLength: 1 })}
placeholder="email"
/>
<input
type="password"
{...register("password", { required: true, minLength: 1 })}
placeholder="password"
/>
<button type="submit">Send</button>
</form>
</div>
);
}
CodePudding user response:
The redirect
utility function only works within a Data router (introduced in `[email protected]) and only in the route loader or action functions, not within a React component.
You should use the useNavigate
hook in this case. React hooks are only callable from React function components and Custom React Hooks, not in any callbacks. See the Rules of Hooks for more details. Use the navigate
function that is returned by the hook to issue the imperative redirect.
Example:
import axios from "axios";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
export function Login() {
const navigate = useNavigate(); // <-- access navigate function
const onSubmit = async (data) => {
try {
console.log(data);
await axios.post("http://localhost:5000/signup", data);
navigate("/my-route", { replace: true }); // <-- redirect
} catch (error) {
console.error("There was an error!", error);
}
};
return (
<div>
<h1>Blah</h1>
<h4>Signup</h4>
<form key={1} onSubmit={handleSubmit(onSubmitSignup)}>
<input
{...register("email", { required: true, minLength: 1 })}
placeholder="email"
/>
<input
type="password"
{...register("password", { required: true, minLength: 1 })}
placeholder="password"
/>
<button type="submit">Send</button>
</form>
</div>
);
}