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

React中useNavigate跳转后页面瞬间返回登录页问题求助

React登录成功后跳转页面随即返回登录页的问题解决

问题描述

开发调用Login API的简易登录页面,使用React Router的useNavigate钩子实现登录成功后的页面跳转。但输入正确凭证后,目标待办事项页面仅显示一秒就自动返回登录页,作为React新手已困扰一个月。

问题代码

import React, { useEffect, useRef, useState } from "react";
import { useNavigate } from 'react-router-dom';


function Login() {
    const password = useRef("");
    const username = useRef("");
    const validate = useRef("");
    const [usernName, setuserName] = useState([]);
    const [passWord, setpassWord] = useState([]);
    const [success, setSuccess] = useState([{ value: 'false' }]);
    const nav = useNavigate();
    
    const LoginValidate = async (un, pw, e) => {

        let message = "";
        var mheaders = new Headers();
        mheaders.append("Content-Type", "application/json");
        var raw = JSON.stringify({

            "username": un,
            "password": pw
        });

        var requestOptions = {
            method: 'POST',
            headers: mheaders,
            body: raw,
            redirect: 'follow'
        };
        console.log("Hi");

        var res = fetch("http://localhost:8080/v1/user/verifyuser", requestOptions).then(response => response.text()).then(result => {
            if (result === "successful") {
                setSuccess(true);
                console.log("Hiyaaaaa");


            }
            else setSuccess(false);
        });
    }

    return (
        (success ?
            nav('/gettodolist/4') : <div className="loginmaindiv">
                <div >
                    <form onSubmit={() => LoginValidate(usernName, passWord)}>
                        <label>Username</label>
                        <input ref={username} type="text" value={usernName} onChange={(e) => setuserName(e.target.value)}></input>
                        <br />
                        <label>Password</label>
                        <input ref={password} type="password" value={passWord} onChange={(e) => setpassWord(e.target.value)}></input>
                        <br />
                        <input type="submit" value="Login" />
                        <div ref={validate}></div>
                    </form>
                </div>
                <div>

                </div>
            </div>

        )

    )

}

export default Login;

问题分析

  1. 表单默认提交行为未阻止:点击登录按钮触发表单提交时,浏览器会执行默认的页面刷新操作,导致Login组件重新挂载,所有状态重置为初始值,跳转后页面立刻刷新回到登录状态。
  2. success状态初始化错误:初始值设为[{ value: 'false' }](数组对象),后续却赋值布尔值true/false,类型不一致会导致渲染逻辑判断异常。
  3. 在渲染阶段调用navigate:直接在return语句中调用nav('/gettodolist/4'),会在组件每次渲染时触发跳转,结合表单刷新的问题,导致跳转后立刻被重置。

解决方案

  1. 阻止表单默认提交行为:在登录处理函数中接收事件参数,调用e.preventDefault()阻止页面刷新。
  2. 修正success状态初始化:将初始值改为布尔值false,保持类型一致。
  3. 使用useEffect监听状态变化实现跳转:通过useEffect监听success状态,当状态变为true时执行跳转,避免在渲染阶段直接调用导航方法。

修改后的代码

import React, { useEffect, useRef, useState } from "react";
import { useNavigate } from 'react-router-dom';

function Login() {
    const password = useRef("");
    const username = useRef("");
    const validate = useRef("");
    const [usernName, setuserName] = useState(""); // 初始值改为空字符串,匹配输入框类型
    const [passWord, setpassWord] = useState(""); // 同上
    const [success, setSuccess] = useState(false); // 修正为布尔值初始状态
    const nav = useNavigate();

    // 监听success状态变化,触发跳转
    useEffect(() => {
        if (success) {
            nav('/gettodolist/4');
            // 跳转后重置状态,避免后续渲染重复触发跳转
            setSuccess(false);
        }
    }, [success, nav]);
    
    const LoginValidate = async (un, pw, e) => {
        // 阻止表单默认刷新行为
        e.preventDefault();
        
        const mheaders = new Headers();
        mheaders.append("Content-Type", "application/json");
        const raw = JSON.stringify({
            "username": un,
            "password": pw
        });

        const requestOptions = {
            method: 'POST',
            headers: mheaders,
            body: raw,
            redirect: 'follow'
        };

        try {
            const response = await fetch("http://localhost:8080/v1/user/verifyuser", requestOptions);
            const result = await response.text();
            if (result === "successful") {
                setSuccess(true);
                console.log("Hiyaaaaa");
            } else {
                setSuccess(false);
                // 登录失败提示
                validate.current.textContent = "用户名或密码错误";
            }
        } catch (error) {
            console.error("登录请求失败:", error);
            setSuccess(false);
            validate.current.textContent = "登录请求失败,请稍后重试";
        }
    }

    return (
        <div className="loginmaindiv">
            <div>
                <form onSubmit={(e) => LoginValidate(usernName, passWord, e)}>
                    <label>Username</label>
                    <input 
                        ref={username} 
                        type="text" 
                        value={usernName} 
                        onChange={(e) => setuserName(e.target.value)}
                    ></input>
                    <br />
                    <label>Password</label>
                    <input 
                        ref={password} 
                        type="password" 
                        value={passWord} 
                        onChange={(e) => setpassWord(e.target.value)}
                    ></input>
                    <br />
                    <input type="submit" value="Login" />
                    <div ref={validate}></div>
                </form>
            </div>
            <div></div>
        </div>
    )
}

export default Login;

额外优化点

  • 将输入框状态的初始值从数组改为空字符串,符合输入值的类型规范。
  • 使用async/await替代链式then,让异步代码逻辑更清晰易读。
  • 添加请求错误捕获逻辑,给用户展示明确的失败提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:20:45