如何通过Context API将id属性传递给Next.js动态路由?
动态路由中无法获取id属性的解决方案
我在将id属性传递给CartItemPage.jsx下的动态路由[id]/page.jsx时遇到了问题。我用类似React Context API的状态管理存储购物车商品数组并渲染购物车,项目包含首页和商品列表页,列表页内有CartItem组件(实际为商品展示组件)。点击这些组件时需跳转至对应商品的CartItemPage/[id]页面,但无法获取到id属性。
相关代码
CartItem组件代码
'use client'; import Link from 'next/link'; import styles from './CartItem.module.css'; import { useState, useEffect } from 'react'; import { useAppStore } from '../../app/Context/store'; const CartItem = ({ data }) => { const [addedToCart, setAddedToCart] = useState(false); const { addToCart, cartItems } = useAppStore(); useEffect(() => { if (cartItems.some(cartItem => cartItem.id === data.id)) { setAddedToCart(true); } else { setAddedToCart(false); } }, [cartItems]); const handleAddToCart = data => { if (cartItems.some(cartItem => cartItem.title === data.title)) { setAddedToCart(true); } else { addToCart(data); setAddedToCart(true); console.log(data); console.log(cartItems); } }; return ( <> <div className={styles.productCard}> <Link href={`/cartItemPage/${data.id}`}> <div className='flex items-center flex-col'> <img className={styles.productImage} src={data.image} alt={data.title} /> <h3 className={styles.productTitle}>{data.title}</h3> <p className={styles.productPrice}>{data.price} $</p> {/* 额外详情 */} </div> </Link> <button onClick={() => { handleAddToCart(data); }} className={addedToCart ? styles.addedButton : styles.addButton} > {addedToCart ? '已在购物车' : '加入购物车'} </button> </div> </> ); }; export default CartItem;
动态路由[id]/page.jsx代码(原错误版本)
'use client'; import React, { useEffect, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { useAppStore } from '@/app/Context/store'; const CartItemPage = ({ id }) => { const router = useRouter(); const searchParams = useSearchParams(); const { addToCart, cartItems } = useAppStore(); const [cartItem, setCartItem] = useState(null); useEffect(() => { const fetchCartItem = async () => { try { const response = await fetch(`https://fakestoreapi.com/products/${id}`); const data = await response.json(response.data); setCartItem(data); } catch (error) { console.log(error); } }; if (id) { fetchCartItem(); } }, [id]); return ( <> <div>id: {id}</div> </> ); }; export default CartItemPage;
问题原因及修复方案
核心问题
在Next.js 13+的App Router模式下,动态路由参数不能通过组件props直接接收,原代码中const CartItemPage = ({ id }) => {...}的写法是错误的,需要使用useParams钩子来获取路由参数。此外,原fetch请求中response.json(response.data)的写法有误,response.json()无需传入参数。
修复后的动态路由页面代码
'use client'; import React, { useEffect, useState } from 'react'; import { useParams } from 'next/navigation'; import { useAppStore } from '@/app/Context/store'; const CartItemPage = () => { const params = useParams(); const id = params.id; const { addToCart, cartItems } = useAppStore(); const [cartItem, setCartItem] = useState(null); useEffect(() => { const fetchCartItem = async () => { try { const response = await fetch(`https://fakestoreapi.com/products/${id}`); const data = await response.json(); setCartItem(data); } catch (error) { console.log(error); } }; if (id) { fetchCartItem(); } }, [id]); return ( <> <div>id: {id}</div> {cartItem && ( <div className="product-detail"> <h2>{cartItem.title}</h2> <img src={cartItem.image} alt={cartItem.title} width={200} /> <p className="price">{cartItem.price} $</p> <p className="description">{cartItem.description}</p> </div> )} </> ); }; export default CartItemPage;
额外检查点
- 确认路由结构正确:需为
app/cartItemPage/[id]/page.jsx(App Router模式下的标准动态路由结构)。 - 确保
CartItem组件中的data.id存在且为有效数值,否则生成的路由会缺失id参数。
内容的提问来源于stack exchange,提问作者ivan kovba
相关产品推荐
相关产品推荐

