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

React项目中如何通过Contentful的client.getEntries获取单个产品的图片与标题

问题描述

我已经能在React项目的产品页面展示所有商品的图片与标题,现在需要实现点击商品跳转至单个产品页面。当前用于获取全部产品数据的函数如下:

const client = createClient({
    accessToken: 's4HlIPhRkQvXB2xEu8l28',
    space: 'zpu5y6hd',
})

const useFetchProducts = () => {
    const [product, setProduct] = useState([]);

    const getData = async () => {
        const res = await client.getEntries({ content_type: 'products' });
        const product = res.items.map((item) => {
            const { image, title } = item.fields;
            const id = item.sys.id;
            const img = image?.fields?.file?.url;
            return { img, title, id }
        });
        setProduct(product)
        //console.log(product)
    }
    useEffect(() => {
        getData()
    }, [])
    return { product }
}; 

该函数返回的数据结构示例:

[
  {
    id: "EEZDQsjqlxfJhKTlC622p",
    img: "//images.ctfassets.net/zpu537igy6hd/10jOjKpdTYAYRVc197KlAs/60910da04dceab7acda47c042261776e/397526804_263713576623932_2944288645324919698_n.jpg",
    title: "Winning Team"
  },
  {
    id: "30cJG3qFu7XBrwckoTmYMD",
    img: "//images.ctfassets.net/zpu537igy6hd/2fat5G5gnOIT00YAdoSVZg/ea3f8c44b62cf977bc8a0d5b3e4eeea7/397492507_267421149586508_6988846565487064728_n.jpg",
    title: "Elf on the Shelf"
  }
]

请问如何使用client.getEntries获取单个产品而非全部产品,并获取其图片与标题值?

解决方案

1. 配置路由并添加跳转链接

先确保已安装并配置React Router(以v6为例),在产品列表组件中给每个商品项添加跳转链接,将产品ID作为路由参数传递:

// 产品列表组件示例
import { Link } from 'react-router-dom';
import { useFetchProducts } from './useFetchProducts';

const ProductList = () => {
  const { product: products } = useFetchProducts();

  return (
    <div className="product-list">
      {products.map(product => (
        <div key={product.id} className="product-item">
          <img src={`https:${product.img}`} alt={product.title} />
          {/* 添加跳转链接,传入产品ID作为路由参数 */}
          <Link to={`/product/${product.id}`}>{product.title}</Link>
        </div>
      ))}
    </div>
  );
};

同时在路由配置文件中添加单个产品页面的路由规则:

// App.js 或路由配置文件
import { Routes, Route } from 'react-router-dom';
import ProductList from './ProductList';
import ProductDetail from './ProductDetail';

function App() {
  return (
    <Routes>
      <Route path="/" element={<ProductList />} />
      {/* 定义带产品ID参数的路由 */}
      <Route path="/product/:productId" element={<ProductDetail />} />
    </Routes>
  );
}

2. 创建获取单个产品的自定义Hook

新建一个Hook,通过sys.id过滤条件精准获取指定ID的产品:

import { useState, useEffect } from 'react';
import { createClient } from 'contentful';

const client = createClient({
  accessToken: 's4HlIPhRkQvXB2xEu8l28',
  space: 'zpu5y6hd',
});

const useFetchSingleProduct = (productId) => {
  const [product, setProduct] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  const getSingleProduct = async () => {
    try {
      setLoading(true);
      // 通过sys.id过滤,仅获取指定ID的产品
      const res = await client.getEntries({
        content_type: 'products',
        'sys.id': productId,
      });

      if (res.items.length === 0) {
        throw new Error('产品不存在');
      }

      // 提取单个产品的图片、标题和ID
      const item = res.items[0];
      const { image, title } = item.fields;
      const id = item.sys.id;
      const img = image?.fields?.file?.url;

      setProduct({ img, title, id });
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (productId) {
      getSingleProduct();
    }
  }, [productId]);

  return { product, loading, error };
};

export default useFetchSingleProduct;

3. 在单个产品页面渲染数据

在单个产品页面组件中,通过useParams获取路由中的产品ID,调用Hook获取数据并渲染:

// ProductDetail.js
import { useParams } from 'react-router-dom';
import useFetchSingleProduct from './useFetchSingleProduct';

const ProductDetail = () => {
  const { productId } = useParams();
  const { product, loading, error } = useFetchSingleProduct(productId);

  if (loading) return <div>加载中...</div>;
  if (error) return <div>错误:{error}</div>;
  if (!product) return <div>未找到产品</div>;

  return (
    <div className="product-detail">
      <h1>{product.title}</h1>
      <img src={`https:${product.img}`} alt={product.title} />
    </div>
  );
};

export default ProductDetail;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 17:32:04