You need to enable JavaScript to run this app. React return中shopFiltered.map is not function及相关异常问题求助
优惠活动
大模型
产品
解决方案
定价
更多

React return中shopFiltered.map is not function及相关异常问题求助

问题根因拆解
  • 核心语法错误:误将数组push方法的返回值作为组件状态
    Array.prototype.push()的返回值是数组完成push操作后的新长度,并非修改后的数组本身。当前代码中setShopFiltered(shopFiltered.push(shop))的写法,本质是把每次push得到的长度数字直接设置为state:
    由于第一个useEffect依赖项为空数组,闭包内捕获的shopFiltered永远是组件首次渲染时的初始空数组引用。每次Geocode异步回调触发时,都会往这个固定的空数组里追加元素,同时把当前数组长度作为新的state值,完全匹配控制台三次打印的表现:
    1. 组件首次挂载时,依赖[shopFiltered]的useEffect执行,打印初始空数组(即观察到的对象数组形式)
    2. 第一个满足距离条件的shop触发push操作,返回长度1并设置为state,触发useEffect打印整型1
    3. 第二个满足距离条件的shop触发push操作,返回长度2并设置为state,触发useEffect打印整型2
      当state被更新为数字类型后,渲染逻辑中调用shopFiltered.map()时,会直接抛出shopFiltered.map is not a function错误——数字类型本身不存在map方法。
  • 异步流程无清理逻辑触发内存泄漏警告
    第一个useEffect中触发了axios请求、循环发起的多个Geocode异步请求,这些异步流程没有配套的取消/状态标记逻辑。如果组件在所有异步请求返回前被卸载,后续异步回调触发时仍会尝试调用setState,就会触发“Can't perform a React state update on an unmounted component”的提示。
修正方案
  • 修正状态更新逻辑,避免类型错误
    摒弃直接操作闭包原数组、传入push返回值的写法,改用函数式状态更新生成全新数组引用:
    将原代码中
    if (dis / 1000 > 10) {
      setShopFiltered(shopFiltered.push(shop));
    }
    
    修改为
    if (dis / 1000 > 10) {
      setShopFiltered((prevShops) => [...prevShops, shop]);
    }
    
  • 增加异步清理逻辑,消除无效状态更新
    在对应useEffect中增加挂载状态标记,在清理函数中标记组件卸载状态,所有异步回调触发setState前先校验挂载状态:
    useEffect(() => {
      let isMounted = true;
      axios
        .get("My url which returns the data")
        .then((resp) => {
          resp.data.forEach((shop) => {
            Geocode.fromAddress(shop.acf.address).then(
              (response) => {
                let dis = getDistance(
                  {
                    latitude: parseFloat(
                      response.results[0].geometry.location.lat
                    ),
                    longitude: parseFloat(
                      response.results[0].geometry.location.lng
                    ),
                  },
                  {
                    latitude: parseFloat(userCoords.lat),
                    longitude: parseFloat(userCoords.lng),
                  }
                );
                if (isMounted && dis / 1000 > 10) {
                  setShopFiltered((prevShops) => [...prevShops, shop]);
                }
              },
              (error) => {
                console.error(error);
              }
            );
          });
        });
      return () => {
        isMounted = false;
      };
    }, []);
    
    注:渲染逻辑中!!shopFiltered && shopFiltered.map()的冗余判断可删除,修正后shopFiltered的类型会始终保持为数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.09 09:15:08