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
相关产品推荐
相关产品推荐

