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

React中结合useEffect与history.block路由守卫获取最新state数据问题

你遇到的是典型的闭包捕获旧值问题,加上history.block的回调注册时机和路由跳转触发时机存在先后差,导致回调无法拿到最新的status值。以下是两种可直接落地的修改方案:


方案1:用useRef存储最新状态(最通用,兼容所有history版本)

核心思路是用可变的ref对象持有最新的status值,不受闭包限制,改造成本极低:

console.log('in the render', status)
// 声明ref存储最新的status
const statusRef = useRef(status)
// 每次render都更新ref为最新值
statusRef.current = status

useEffect(() => {
  console.log('in the useEffect', status)
  const unlisten = history.block(route => {
    // 直接从ref取最新值,不会有闭包旧值问题
    console.log('in the block', statusRef.current)
    return routeGuard({ status: statusRef.current })
  })
  return unlisten
}, []) // 依赖可以留空,不需要每次status变化都重新注册block

方案2:使用react-router官方useBlocker(v6.4+版本适用)

如果你用的是较新版本的react-router,直接用官方封装的useBlocker hook,内部已经处理了状态同步问题:

import { useBlocker } from 'react-router-dom'

const blocker = useBlocker(
  ({ currentLocation, nextLocation }) => {
    console.log('in the block', status)
    // 这里直接取status就是最新值,不需要额外处理
    return !routeGuard({ status })
  }
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:45:04