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

React中用react-router-dom实现密码重置成功后自动延时跳转

React函数组件中useMutation成功后延时跳转登录页的解决方案

问题分析

你之前的写法失效原因如下:

  • 写法1:isSuccess为true时直接return <Redirect>,同步代码优先执行,setTimeout还没触发就完成了跳转,完全没有延时效果。
  • 写法2:setTimeout回调里return JSX无效,因为该回调不是组件的渲染函数,React不会处理这个返回的元素。
  • 写法3:useMutation的onSuccess是异步回调,返回的JSX不会被渲染到页面,且直接return <Redirect>会跳过setTimeout的执行逻辑。

可行方案

方案1:用状态控制<Redirect>渲染

通过useState维护跳转状态,在onSuccess中延时修改状态,组件重新渲染时触发跳转:

import { useState } from 'react';
import { Redirect } from 'react-router-dom';
import { useMutation } from '@tanstack/react-query'; // 根据你的实际query库调整

const PasswordResetPage = () => {
  const [shouldRedirect, setShouldRedirect] = useState(false);
  
  const { mutateAsync, isLoading, isSuccess, error } = useMutation(
    submitPasswordRequest,
    {
      onSuccess: () => {
        // 延时3秒后触发跳转状态
        setTimeout(() => {
          setShouldRedirect(true);
        }, 3000);
      },
    }
  );

  // 优先判断跳转状态,满足则渲染Redirect
  if (shouldRedirect) {
    return <Redirect to="/login" />;
  }

  return (
    <div>
      {/* 密码重置表单内容 */}
      {isLoading && <p>重置中,请稍候...</p>}
      {isSuccess && <div className="success-chip">密码重置成功!3秒后自动跳转登录页</div>}
      {error && <p className="error-text">重置失败:{error.message}</p>}
    </div>
  );
};

export default PasswordResetPage;

方案2:使用useHistory实现跳转(解决v5中push不可用问题)

在react-router-dom v5的函数组件中,必须通过useHistory钩子获取history对象,而不是直接导入history实例,这样才能正常调用push方法:

import { useHistory } from 'react-router-dom';
import { useMutation } from '@tanstack/react-query';
import { useEffect } from 'react';

const PasswordResetPage = () => {
  const history = useHistory();
  
  const { mutateAsync, isLoading, isSuccess, error } = useMutation(
    submitPasswordRequest
  );

  // 监听isSuccess状态,成功后延时跳转
  useEffect(() => {
    let timer;
    if (isSuccess) {
      timer = setTimeout(() => {
        history.push('/login');
      }, 3000);
    }
    // 组件卸载时清除定时器,避免内存泄漏
    return () => clearTimeout(timer);
  }, [isSuccess, history]);

  return (
    <div>
      {/* 表单内容 */}
      {isLoading && <p>重置中...</p>}
      {isSuccess && <div className="success-chip">密码重置成功!即将跳转登录页</div>}
      {error && <p>重置失败:{error.message}</p>}
    </div>
  );
};

export default PasswordResetPage;

额外注意事项

  • 如果使用定时器,记得在组件卸载时清除,避免内存泄漏(方案2中已经通过useEffect的清理函数实现)。
  • 确保组件处于<Router>组件的上下文范围内,useHistory和<Redirect>才能正常工作。
  • 若使用的是其他mutation库(如react-query之外的),只需调整useMutation的写法,核心逻辑保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 07:16:30