使用useBlocker钩子遇TypeError:blocker.reset/proceed非函数
解决React Router useBlocker中blocker.proceed/reset不是函数的问题
你遇到的问题是因为React Router的useBlocker钩子返回的对象并没有proceed或reset方法,这些方法属于navigation对象,而非blocker本身。下面是具体的修复方案:
错误原因
你参照的示例可能混淆了useBlocker的用法,blocker对象仅用于定义拦截逻辑,并不提供主动取消拦截的方法。要取消拦截,需要通过修改拦截条件或使用navigation对象来处理。
修复代码
- 新增状态控制是否允许导航,同时引入
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]);
- 如果需要在拦截弹窗中处理确认/取消跳转(比如用户点击离开时的弹窗),可以结合
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
相关产品推荐
相关产品推荐

