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

Firebase sendPasswordResetEmail的then导航失效,提交后自动跳转首页

忘记密码页面导航失效且自动跳首页问题

我搭建了一个基础的忘记密码页面,正在实现Firebase的sendPasswordResetEmail功能。该功能可正常触发,但在成功回调(then)中添加navigate导航功能时无法生效。无论操作成功或失败,提交后页面都会自动跳转到首页,URL末尾带有“?”,请问这是什么原因?

原代码

import React, { useState } from "react";
import { useNavigate } from 'react-router-dom';
import { getAuth, sendPasswordResetEmail } from "firebase/auth";

import '../scss/pages/ForgotPage.scss'

function ForgotPassword() {

    document.title = 'Acquired | Forgot Password';

    const navigate = useNavigate();
    const navigateTo = (path) => {
        navigate(path)
    }

    const [email, setEmail] = useState('')
    const auth = getAuth();


    const forgotPassword = (Email) => {
        sendPasswordResetEmail(auth, Email)
            .then(function () {
                console.log('success');
            }).catch((error) => {
                const errorCode = error.code;
                const errorMessage = error.message;
                console.log(errorMessage);
            });
    }

    return (
        <div className='pageBackground'>
            <div className='loginContainer'>
                <div className="regForm-container sign-in-container">
                    <form className='regForm' action="/">
                        <h1 className='formHeader'>Enter your login email</h1>
                        <input className='loginInput' type="email" placeholder="Email" onChange={(a) => setEmail(a.target.value)} value={email} required />
                        <button className='ghost' onClick={() => forgotPassword(email)}>Reset</button>
                    </form>
                </div>
                <div className="overlay-container">
                    <div className="overlay">
                        <div className="overlay-panel overlay-right">
                            <h1 className='formHeader'>Don't sweat it</h1>
                            <h5 className='regP'>Forgetting a password happens to the best of us!</h5>
                            <h5 className='regP'>But just in case you remembered</h5>
                            <button className='ghostOther' onClick={() => navigate('/signin')}>Log In</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}
export default ForgotPassword;

问题原因

核心问题是表单的默认提交行为:

  • 按钮放在<form>标签内,默认类型为submit,点击后会触发表单的默认提交动作
  • 表单设置了action="/",提交后会直接跳转到首页;URL末尾的?是表单默认以GET方式提交的特征(未指定method时默认用GET)
  • 浏览器的同步跳转行为会直接中断回调里的异步导航逻辑,导致navigate根本没机会生效

解决办法(两种任选其一)

方法1:阻止按钮点击的默认行为

修改forgotPassword函数,接收事件对象并阻止默认提交:

const forgotPassword = (e, Email) => {
    e.preventDefault(); // 阻止表单默认提交
    sendPasswordResetEmail(auth, Email)
        .then(function () {
            console.log('success');
            navigate('/signin'); // 导航可正常生效
        }).catch((error) => {
            const errorCode = error.code;
            const errorMessage = error.message;
            console.log(errorMessage);
        });
}

同时修改按钮点击事件,传入事件对象:

<button className='ghost' onClick={(e) => forgotPassword(e, email)}>Reset</button>

方法2:将按钮设为非提交类型

给按钮添加type="button",避免触发表单提交:

<button className='ghost' type="button" onClick={() => forgotPassword(email)}>Reset</button>

同时可以去掉表单的action="/",因为不再需要默认提交行为:

<form className='regForm'>

修改后的完整代码示例(以方法2为例)

import React, { useState } from "react";
import { useNavigate } from 'react-router-dom';
import { getAuth, sendPasswordResetEmail } from "firebase/auth";

import '../scss/pages/ForgotPage.scss'

function ForgotPassword() {

    document.title = 'Acquired | Forgot Password';

    const navigate = useNavigate();

    const [email, setEmail] = useState('')
    const auth = getAuth();


    const forgotPassword = (Email) => {
        sendPasswordResetEmail(auth, Email)
            .then(function () {
                console.log('success');
                navigate('/signin'); // 导航正常执行
            }).catch((error) => {
                const errorCode = error.code;
                const errorMessage = error.message;
                console.log(errorMessage);
            });
    }

    return (
        <div className='pageBackground'>
            <div className='loginContainer'>
                <div className="regForm-container sign-in-container">
                    <form className='regForm'>
                        <h1 className='formHeader'>Enter your login email</h1>
                        <input className='loginInput' type="email" placeholder="Email" onChange={(a) => setEmail(a.target.value)} value={email} required />
                        <button className='ghost' type="button" onClick={() => forgotPassword(email)}>Reset</button>
                    </form>
                </div>
                <div className="overlay-container">
                    <div className="overlay">
                        <div className="overlay-panel overlay-right">
                            <h1 className='formHeader'>Don't sweat it</h1>
                            <h5 className='regP'>Forgetting a password happens to the best of us!</h5>
                            <h5 className='regP'>But just in case you remembered</h5>
                            <button className='ghostOther' onClick={() => navigate('/signin')}>Log In</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}
export default ForgotPassword;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:55:25