如何修复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]; };
修复说明
- 为每个请求参数(
stopId/route)维护独立的状态和结果,通过缓存对象存储,避免全局变量共享导致的覆盖问题。 - 增加缓存逻辑,相同参数的请求只会发起一次,提升性能。
内容的提问来源于stack exchange,提问作者The KNVB
相关产品推荐
相关产品推荐

