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

React Suspense:如何向函数组件外的fetch传递动态参数?

React Suspense 结合动态ID获取数据的解决方案

核心思路是将数据获取逻辑封装为接收动态ID参数的工厂函数,在组件内部拿到ID后再调用该函数,利用Suspense捕获异步请求的Promise,以此解决外部无法获取动态参数的问题。

修改后的代码示例

Screen.js(无需调整,保持原结构即可)

import { Suspense } from 'react';
import ProductDetailScreen from './ProductDetail';
import Spinner from './Spinner';

export default function Screen() {
  return (
    <Suspense fallback={<Spinner />}>
      <ProductDetailScreen />
    </Suspense>
  );
}

ProductDetail.js

import { useRoute } from '@react-navigation/native';
import axios from 'axios'; // 替换为你实际使用的请求库

// 缓存已请求的商品数据,避免重复发起相同请求
const productCache = new Map();

// 接收商品ID的工厂函数,处理数据获取与Suspense触发逻辑
function getProductData(productId) {
  // 检查缓存中是否已有该商品的请求记录
  if (productCache.has(productId)) {
    const cacheItem = productCache.get(productId);
    // 数据已加载完成,直接返回
    if (cacheItem.status === 'resolved') {
      return cacheItem.value;
    }
    // 请求正在进行中,抛出Promise让Suspense捕获
    throw cacheItem.promise;
  }

  // 无缓存记录,发起新请求
  const requestPromise = axios.get(`/api/products/${productId}`)
    .then(res => {
      // 请求成功,更新缓存为已完成状态
      productCache.set(productId, {
        status: 'resolved',
        value: res.data
      });
      return res.data;
    })
    .catch(err => {
      // 请求失败,更新缓存为错误状态
      productCache.set(productId, {
        status: 'rejected',
        value: err
      });
      throw err;
    });

  // 将正在进行的请求存入缓存
  productCache.set(productId, {
    status: 'pending',
    promise: requestPromise
  });

  // 抛出Promise,触发Suspense的fallback显示
  throw requestPromise;
}

export default function ProductDetailScreen() {
  // 通过useRoute获取路由参数中的商品ID
  const route = useRoute();
  const { productId } = route.params;

  // 调用带动态ID的获取函数,Suspense会自动处理加载状态
  const productData = getProductData(productId);

  return (
    <View>
      <Text>{productData.name}</Text>
      <Text>{productData.description}</Text>
      {/* 其他商品详情UI */}
    </View>
  );
}

关键说明

  • 缓存机制:用Map存储每个商品ID的请求状态(pending/resolved/rejected),避免重复请求同一商品,同时处理请求失败的场景。
  • 动态参数传递:在组件内部通过useRoute拿到商品ID后,再调用数据获取函数,完美解决Suspense要求外部执行fetch时无法获取动态参数的问题。
  • Suspense触发逻辑:当getProductData抛出Promise时,Suspense会自动显示fallback组件,直到Promise resolve后再渲染商品详情内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:13:16