You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js表单提交时router.push导航失效问题求助

Next.js注册表单提交后router.push跳转失效问题

我在Next.js中开发注册表单,期望注册成功后通过router.push跳转至OTP验证页面,但提交表单时该导航操作未生效。

代码实现

"use client"
import React, { useState } from "react";
import Link from "next/link";
import { useForm } from "react-hook-form";
import styles from "./registerForm.module.css";
import { motion } from "framer-motion";
import { useRouter } from "next/navigation";
import apiLinks from "@/api/api-links";
import { POST } from "@/api/api-calls";

const RegisterForm = () => {
  const { register, handleSubmit, formState: { errors }, getValues } = useForm();
  const router = useRouter();
  const [isLoading, setIsLoading] = useState(false);

  const onSubmit = async (data) => {
    setIsLoading(true);
    try {
      const response = await POST({ path: apiLinks['auth']['register'], body: data });
      router.push(`/otp/${data.email}`);
    } catch (error) {
      if (error.response) {
        // Handle HTTP errors
        console.error('HTTP Error:', error.response.data);
      } else {
        // Handle non-HTTP errors (e.g., network error)
        console.error('Error:', error.message);
      }
    }
    setIsLoading(false);
  };

  return (
    <motion.div
      initial={{ y: "5vh", opacity: 0 }}
      animate={{ y: 0, opacity: 1 }}
      transition={{ duration: 0.9, ease: "easeOut" }}
      style={{ overflow: "hidden" }}
      className={styles.formContainer}
    >
      <h1 className={styles.text}>Register</h1>
      <form className={styles.form} onSubmit={handleSubmit(onSubmit)}>
        <label>First Name</label>
        <input
          type="text"
          name="firstName"
          placeholder="E.g. John"
          className={`${styles.input} ${errors.firstName ? styles.errorInput : ""}`}
          {...register("firstName", {
            required: "First name is required",
            pattern: {
              value: /^[A-Za-z]+$/,
              message: "First name should only contain letters",
            },
          })}
        />
        {errors.firstName && (
          <span className={styles.errorMessage}>{errors.firstName.message}</span>
        )}

        <label>Last Name</label>
        <input
          type="text"
          name="lastName"
          placeholder="E.g. Doe"
          className={`${styles.input} ${errors.lastName ? styles.errorInput : ""}`}
          {...register("lastName", {
            required: "Last name is required",
            pattern: {
              value: /^[A-Za-z]+$/,
              message: "Last name should only contain letters",
            },
          })}
        />
        {errors.lastName && (
          <span className={styles.errorMessage}>{errors.lastName.message}</span>
        )}

        <label>Phone Number</label>
        <input
          type="tel"
          name="phoneNumber"
          placeholder="E.g. 123-456-7890"
          className={`${styles.input} ${errors.phoneNumber ? styles.errorInput : ""}`}
          {...register("phoneNumber", {
            required: "Phone number is required",
            pattern: {
              value: /^\d{3}-\d{3}-\d{4}$/,
              message: "Phone number must be in the format 123-456-7890",
            },
          })}
        />
        {errors.phoneNumber && (
          <span className={styles.errorMessage}>{errors.phoneNumber.message}</span>
        )}

        <label>Email</label>
        <input
          type="text"
          name="email"
          placeholder="E.g parent@gmail.com"
          className={`${styles.input} ${errors.email ? styles.errorInput : ""}`}
          {...register("email", {
            required: "Email is required",
            pattern: {
              value: /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/,
              message: "Invalid email address",
            },
          })}
        />
        {errors.email && (
          <span className={styles.errorMessage}>{errors.email.message}</span>
        )}

        <label>Password</label>
        <input
          type="password"
          name="password"
          placeholder="Password"
          className={`${styles.input} ${errors.password ? styles.errorInput : ""}`}
          {...register("password", {
            required: "Password is required",
            minLength: {
              value: 8,
              message: "Password must be at least 8 characters",
            },
          })}
        />
        {errors.password && (
          <span className={styles.errorMessage}>{errors.password.message}</span>
        )}

        <label>Repeat Password</label>
        <input
          type="password"
          name="repeatPassword"
          placeholder="Repeat Password"
          className={`${styles.input} ${errors.repeatPassword ? styles.errorInput : ""}`}
          {...register("repeatPassword", {
            required: "Repeat Password is required",
            validate: {
              matchesPassword: (value) =>
                value === getValues("password") || "Passwords do not match",
            },
          })}
        />
        {errors.repeatPassword && (
          <span className={styles.errorMessage}>{errors.repeatPassword.message}</span>
        )}

        <button type="submit" disabled={isLoading}>
          {isLoading ? "Registering..." : "Register"}
        </button>
        <div className={styles.registerContainer}>
          Already have an account?
          <Link href="/login" className={styles.loginLink}>
            Login
          </Link>
        </div>
      </form>
    </motion.div>
  );
}

export default RegisterForm;

关键信息

  • 使用useRouter从next/navigation导航至OTP页面
  • 通过自定义POST函数发送注册表单数据
  • 注册成功后尝试通过router.push(/otp/${data.email})跳转至/otp/[email]路径
  • 表单提交后并未触发导航

已排查项

  • POST请求正常工作并返回成功响应
  • data.email包含正确的邮箱地址
  • 控制台无任何与导航相关的错误

疑问

为何router.push未按预期工作?我的代码中是否存在遗漏或错误?

内容的提问来源于stack exchange,提问作者SWE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 22:27:02