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

状态变更时重置navigation addListener无效,返回remove仍未解决

问题修复方案

你的代码核心问题是清理函数的位置错误,导致旧的监听器没有在依赖变更时被正确移除,同时依赖数组不完整也会引发闭包问题。以下是修正后的代码及说明:

错误原因分析

原代码中,你把移除监听器的return () => remove()写在了navigation.addListener的回调函数内部,而不是作为useEffect的返回值。这意味着这个清理逻辑永远不会被执行,旧的监听器会一直存在,状态变更时多个监听器同时触发,导致功能异常。

修正后的代码

useEffect(() => {
  const { page, pageIdx, tab } = pageInfo;

  // 定义监听器回调
  const handleStateChange = ({ data: { state: { routes, index } } }) => {
    if (routes?.[index]?.name === name) { // 加可选链避免潜在报错
      if (pageIdx) {
        getMatchItem(`usr/goods/match/buy/history/${tab}/${page}`);
      } else {
        getItem(`usr/goods/auction/bid/${tab}/${page}`);
      }
    }
  };

  // 添加监听器并获取移除函数
  const removeListener = navigation.addListener('state', handleStateChange);

  // 作为useEffect的返回值,在依赖变更/组件卸载时移除监听器
  return removeListener;

}, [pageInfo, navigation, name, getMatchItem, getItem]); // 补全所有依赖项

关键修正点

  • 调整清理函数位置:将移除监听器的逻辑作为useEffect的返回值,确保React在合适时机(依赖变更、组件卸载)执行清理。
  • 补全依赖数组:把navigation、name、getMatchItem、getItem都加入依赖数组,避免闭包导致的旧值引用问题。如果getMatchItem和getItem是组件内部定义的函数,建议用useCallback包裹,防止不必要的重渲染。
  • 添加可选链:在访问routes[index].name时使用?.,避免状态未初始化时的TypeError。

内容的提问来源于stack exchange,提问作者Youngsung Choi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:02:57