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

React跨函数调用无法获取useReducer最新state值问题

问题现象

通过useReducer管理分页、排序、筛选相关的TableProps表格属性,表格内交互触发状态变更时TableProps可正常更新,但调用删除逻辑后执行fetch函数时,获取到的TableProps始终为初始值initialProps。逻辑中同时使用createContext向子组件传递状态与方法,所有相关代码均包裹在接收children参数的函数组件内。

原始代码片段:

const [TableProps, dispatch] =  useReducer(TableReducer, initialProps);

const doDelete = async (id: number) => {
  setLoading(true);
  const response: Responsetype = await _delete<Responsetype>(TableProps.fetch + '/' + id, {});
  if (response.code) {
    alert(response);
    await fetch();
  }
  setLoading(false);
}

const fetch = () => {
  console.log(TableProps)  // 始终返回初始值
}
const context = React.CreateContext();
const value = {doDelete, TableProps .....}
return (
  <context.provider value={value}>
    {children}
  </context.provider>
);
问题原因

这是典型的React闭包陷阱:

  • doDelete、fetch是组件渲染时创建的函数,异步执行删除逻辑的过程中,函数内部捕获的是函数创建时所在渲染周期的TableProps快照,如果后续TableProps更新但函数引用没有同步更新,异步回调里拿到的永远是初始渲染时的旧值。
  • 直接在Context value中传递每次渲染新生成的普通函数、普通对象,很容易导致子组件拿到旧的函数引用,触发闭包问题。
修复方案
  • 用useCallback包裹操作函数,将用到的状态加入依赖数组,保证状态更新后函数引用同步更新,始终能拿到最新的状态值:
const fetch = useCallback(() => {
  console.log(TableProps)
  // 补充列表拉取逻辑
}, [TableProps])

const doDelete = useCallback(async (id: number) => {
  setLoading(true);
  const response: Responsetype = await _delete<Responsetype>(TableProps.fetch + '/' + id, {});
  if (response.code) {
    alert(response);
    await fetch();
  }
  setLoading(false);
}, [TableProps, fetch])
  • 用useMemo包裹Context传递的value值,避免每次渲染生成新对象导致子组件异常缓存旧值:
const contextValue = useMemo(() => ({
  doDelete,
  TableProps,
  dispatch
  // 其余需要透传的属性、方法
}), [doDelete, TableProps, dispatch])

return (
  <context.Provider value={contextValue}>
    {children}
  </context.Provider>
)

可选方案:如果不想维护hooks依赖,也可以通过useRef存储最新状态,绕开闭包捕获问题:

const tablePropsRef = useRef(TableProps);
// 每次状态更新同步到ref
useEffect(() => {
  tablePropsRef.current = TableProps;
}, [TableProps])

const fetch = () => {
  // 直接读ref的current属性永远拿到最新值
  console.log(tablePropsRef.current)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:03:20