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

如何修复React Suspense中公交站点信息重复展示问题?

问题修复方案

问题原因

fetchBusStopInfo.js中定义的result和status是模块级全局变量,所有调用该函数的BusStop组件会共享这两个变量。当多个组件同时发起请求时,后续请求的结果会覆盖之前的,最终所有组件都显示最后一个请求返回的站点名称,导致重复。

同样,fetchBusStopListByRoute.js也存在相同的全局变量问题,虽然当前只调用一次,但为了避免后续扩展出现问题,建议一并修复。

修复代码

修复后的 fetchBusStopInfo.js

import axios from 'axios';

// 用对象缓存每个stopId的请求状态和结果
const cache = {};

export default function fetchBusStopInfo(stopId) {
  // 如果已有缓存,直接返回
  if (cache[stopId]) {
    return cache[stopId];
  }

  let result;
  let status = "pending";

  let api = axios.create();
  api.interceptors.response.use(
    null, // 默认成功处理器
    (error) => {
      console.log(error.toJSON());
      return Promise.reject({
        status: error.response?.status,
        message:
          error.response?.data ?? error.response?.statusText ?? error.message,
      });
    }
  );

  let suspender = api({
    url: `https://data.etabus.gov.hk/v1/transport/kmb/stop/${stopId}`,
    method: 'get',
  }).then(
    (r) => {
      status = 'success';
      result = r.data;
    },
    (e) => {
      status = 'error';
      result = e;
    }
  );

  function read() {
    if (status === 'pending') {
      throw suspender;
    } else if (status === 'error') {
      throw result;
    } else if (status === 'success') {
      return result;
    }
  }

  // 将当前stopId的请求实例存入缓存
  cache[stopId] = { read };
  return cache[stopId];
}

修复后的 fetchBusStopListByRoute.js

import axios from 'axios';

// 用对象缓存不同线路的请求状态和结果
const cache = {};

export default function fetchBusStopListByRoute(route){
  // 如果已有缓存,直接返回
  if (cache[route]) {
    return cache[route];
  }

  let result;
  let status = "pending";

  let api = axios.create();
  api.interceptors.response.use(
    null, // 默认成功处理器
    (error) => {
      console.log(error.toJSON());
      return Promise.reject({
        status: error.response?.status,
        message:
          error.response?.data ?? error.response?.statusText ?? error.message,
      });
    }
  );

  let suspender=api({
    url: `https://data.etabus.gov.hk/v1/transport/kmb/route-stop/${route}/inbound/1`,
    method: 'get',
  }).then(
    (r) => {
      status = 'success';
      result = r.data;
    },
    (e) => {
      status = 'error';
      result = e;
    }
  );

  function read(){
    if (status === 'pending') {
      throw suspender;
    } else if (status === 'error') {
      throw result;
    } else if (status === 'success') {
      return result;
    }
  }

  // 将当前线路的请求实例存入缓存
  cache[route] = { read };
  return cache[route];
};

修复说明

  1. 为每个请求参数(stopId/route)维护独立的状态和结果,通过缓存对象存储,避免全局变量共享导致的覆盖问题。
  2. 增加缓存逻辑,相同参数的请求只会发起一次,提升性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 20:03:27