React中使用router.push回调函数没执行怎么办?

程序猿怡企 阅读 40

我在用React Router 6做编程式导航时遇到问题,调用navigate(‘/next’, { replace: true, onComplete: () => console.log(‘导航完成’) })后地址栏确实跳转了,但控制台没有输出’导航完成’提示。

已经尝试过:


import { useNavigate } from 'react-router-dom';

function MyButton() {
  const navigate = useNavigate();
  return (
    <button 
      onClick={() => navigate('/next', {
        replace: true,
        state: { from: 'home' },
        onComplete: () => console.log('导航完成')
      })}
    >
      跳转页面
    </button>
  );
}

没有报错提示,但就是看不到回调执行。如果把onComplete换成onAbort也能正常触发取消时的提示,但成功后的回调就是不执行…

我来解答 赞 3 收藏
二维码
手机扫码查看
2 条解答
Prog.栾诺
React Router 6 的 navigate 方法根本不支持 onComplete 这种选项,你可能是记错了 API。改成这样:

import { useNavigate } from 'react-router-dom';

function MyButton() {
const navigate = useNavigate();
const handleClick = () => {
navigate('/next', { replace: true, state: { from: 'home' } });
console.log('导航完成');
};
return (
<button onClick={handleClick}>
跳转页面
</button>
);
}


直接在 navigate 后面写逻辑就行,别整那些不存在的回调选项。
点赞 2
2026-02-17 08:03
Code°翼杨
这个问题其实挺常见的,React Router 6的API设计和之前版本有很大的变化,很多人会误以为navigate方法支持一个类似onComplete的回调选项,但其实官方文档里并没有提到这个功能。让我一步步给你讲清楚原因以及怎么解决。

第一步,我们先搞明白navigate函数到底支持什么参数。在React Router 6中,useNavigate返回的navigate函数签名是这样的:
navigate(to, options?)

其中to可以是字符串路径或者一个对象,options目前只支持两个属性:replacestate。也就是说,onComplete这个东西根本就不是官方支持的选项,所以它不会被执行。这也是为什么你用onAbort可以正常工作,因为那是导航被中断时的处理逻辑,而onComplete压根不存在。

第二步,既然navigate不支持回调函数,那怎么实现类似的功能呢?我们可以借助React Router提供的useEffect监听路由变化来完成。具体做法是这样:

1. 使用useLocation钩子来监听当前路由的变化。
2. 在组件中通过useEffect检测路由变化,并在变化后执行你需要的回调逻辑。

下面是修改后的代码示例:

import { useNavigate, useLocation } from 'react-router-dom';
import { useEffect } from 'react';

function MyButton() {
const navigate = useNavigate();
const location = useLocation(); // 获取当前路由信息

useEffect(() => {
// 每次路由变化时都会触发这个effect
console.log('导航完成,当前路径是:', location.pathname);
}, [location]); // 监听location的变化

return (
<button
onClick={() => navigate('/next', {
replace: true,
state: { from: 'home' }
})}
>
跳转页面
</button>
);
}


第三步,解释一下这段代码的工作原理。useLocation会返回当前的路由信息对象,每次路由变化时,这个对象都会更新。我们在useEffect中监听location的变化,当它发生变化时,说明导航已经完成,此时就可以执行你需要的回调逻辑了。这里我用了console.log来模拟你的回调函数,你可以根据需要替换成其他逻辑。

第四步,如果你觉得每次都要手动写这些逻辑太麻烦,可以封装一个自定义hook来简化操作。比如这样:

import { useNavigate, useLocation } from 'react-router-dom';
import { useEffect } from 'react';

function useNavigateWithCallback(callback) {
const navigate = useNavigate();
const location = useLocation();

useEffect(() => {
if (callback && typeof callback === 'function') {
callback(location.pathname); // 把当前路径传给回调函数
}
}, [location, callback]);

return navigate; // 返回原始的navigate函数
}

// 使用自定义hook的组件
function MyButton() {
const navigate = useNavigateWithCallback((path) => {
console.log('导航完成,跳转到了:', path);
});

return (
<button
onClick={() => navigate('/next', {
replace: true,
state: { from: 'home' }
})}
>
跳转页面
</button>
);
}


总结一下,React Router 6的navigate函数确实不支持onComplete这样的回调选项,这是设计上的限制。但我们可以通过监听路由变化的方式实现类似的功能,甚至可以封装成一个通用的hook来复用。希望这个解决方案能帮你解决问题,如果还有疑问随时问我。
点赞 3
2026-02-14 11:19