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

使用useBlocker钩子遇TypeError:blocker.reset/proceed非函数

解决React Router useBlocker中blocker.proceed/reset不是函数的问题

你遇到的问题是因为React Router的useBlocker钩子返回的对象并没有proceed或reset方法,这些方法属于navigation对象,而非blocker本身。下面是具体的修复方案:

错误原因

你参照的示例可能混淆了useBlocker的用法,blocker对象仅用于定义拦截逻辑,并不提供主动取消拦截的方法。要取消拦截,需要通过修改拦截条件或使用navigation对象来处理。

修复代码

  1. 新增状态控制是否允许导航,同时引入useNavigate用于跳转:
import { useBlocker, useNavigate } from 'react-router-dom';
import { useState, useEffect } from 'react';

// ...其他代码

const navigate = useNavigate();
const [allowNavigation, setAllowNavigation] = useState(false);

// 修改拦截条件,当allowNavigation为true时不再拦截
const blocker = useBlocker(
  ({ currentLocation, nextLocation }) =>
    !allowNavigation &&
    formData.projectName !== '' &&
    currentLocation.pathname !== nextLocation.pathname
);

useEffect(() => {
  if (createSolutionSpaceRes || createSolutionSpaceErrorRes) {
    // 表单提交完成,允许导航并跳转到仪表盘
    setAllowNavigation(true);
    navigate('/dashboard');
  }
  return () => {
    // 组件卸载时重置导航状态
    setAllowNavigation(false);
  };
}, [createSolutionSpaceRes, createSolutionSpaceErrorRes, navigate]);
  1. 如果需要在拦截弹窗中处理确认/取消跳转(比如用户点击离开时的弹窗),可以结合useNavigation:
const navigation = useNavigation();

// 在弹窗的确认按钮点击事件中调用
const handleConfirmLeave = () => {
  navigation.proceed(); // 允许跳转
};

const handleCancelLeave = () => {
  navigation.cancel(); // 取消跳转
};

核心逻辑说明

  • 通过allowNavigation状态动态控制拦截条件,表单提交完成后将其设为true,拦截逻辑自动失效。
  • 跳转操作直接使用useNavigate提供的navigate函数,无需依赖blocker对象。
  • 拦截弹窗中的确认/取消操作,需要使用useNavigation获取的navigation对象来调用proceed()或cancel()。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:20:02