React中点击卡片组件时如何携带组件数据跳转加载对应新页面
React 商品卡片点击跳转详情页实现方案
所有方案都兼容你现有.map()遍历渲染卡片的逻辑,不需要重构现有列表代码,按自己的项目场景选就行:
方案1:React Router 动态路由传参(生产环境首选)
这是React单页应用做页面跳转的标准方案,无整页刷新,体验流畅,支持链接分享、页面刷新保留内容,是绝大多数电商网站的实现逻辑。
- 先安装路由依赖:
npm install react-router-dom - 项目里配置路由规则,除了你现有的商品列表页路由,新增一个带动态参数的详情页路由,路径格式为
/product/:id,:id就是用来接收商品唯一标识的占位符。 - 卡片渲染时直接绑定跳转逻辑,两种写法选一种就行:
import { Link, useNavigate } from 'react-router-dom' // 写法1:无额外前置逻辑直接跳,用Link组件包裹卡片内容最省事 {productList.map(product => ( <div key={product.id} className="product-card"> <Link to={`/product/${product.id}`} className="card-link"> {/* 这里放你原来写的卡片内容:封面图、标题、价格等 */} <img src={product.cover} alt={product.name} /> <h3>{product.name}</h3> <p className="price">¥{product.price}</p> </Link> </div> ))} // 写法2:点击后要先做埋点、商品状态判断等逻辑,用useNavigate钩子控制跳转 const navigate = useNavigate() const handleCardClick = (product) => { // 这里加你的前置逻辑,比如上报点击数据、判断商品是否下架 navigate(`/product/${product.id}`) } // 卡片上绑定onClick事件即可:<div onClick={() => handleCardClick(product)}>
- 详情页组件里用
useParams()拿到路由携带的商品id,去你存商品数据的独立js文件里匹配对应数据渲染:
import { useParams } from 'react-router-dom' import { productList } from '@/data/products' // 替换成你自己的商品数据文件路径 export default function ProductDetail() { const { id } = useParams() // 注意路由拿到的id默认是字符串,如果你的数据里id是数字类型,要转类型再匹配 const currentProduct = productList.find(item => item.id === Number(id)) // 兜底:id匹配不到商品时的提示 if (!currentProduct) return <div className="empty">商品不存在或已下架</div> // 下面写你自己的详情页渲染逻辑即可 return ( <div className="detail-container"> <img src={currentProduct.cover} alt={currentProduct.name} /> <h1>{currentProduct.name}</h1> <p className="price">¥{currentProduct.price}</p> <div className="desc">{currentProduct.description}</div> </div> ) }
小提示:后续如果商品数据改成从后端接口获取,只需要在详情页拿到id后调用接口拉取对应商品数据即可,其他逻辑不用改。
方案2:路由携带全量数据跳转(适合小数据量Demo)
如果不想在详情页重新匹配/拉取数据,可以在跳转的时候直接把当前商品的全量数据通过路由state带过去:
// 跳转时传state navigate('/product/detail', { state: { productInfo: product } })
详情页用useLocation()拿数据即可:
import { useLocation } from 'react-router-dom' export default function ProductDetail() { const { state } = useLocation() const currentProduct = state?.productInfo // 必须做兜底:用户刷新页面、直接输链接进详情页时state会丢失 if (!currentProduct) return <div className="empty">请从商品列表页进入</div> // 渲染逻辑和方案1一致 }
注意:这个方案的缺陷是用户刷新页面、分享链接时会丢失传递的数据,必须加兜底跳转或者重新拉取数据的逻辑,不适合正式生产环境用。
方案3:原生JS跳转(零依赖快速实现,仅适合练手Demo)
如果暂时不想引入路由库,想快速看到效果,可以直接用原生JS的跳转API,通过URL查询参数传id:
const handleCardClick = (product) => { // 当前页跳转 window.location.href = `/detail.html?id=${product.id}` // 要新开标签页就用window.open // window.open(`/detail.html?id=${product.id}`, '_blank') }
详情页里解析URL拿到id,再匹配数据渲染即可。
缺陷:会触发整页刷新,破坏React单页应用的流畅体验,正式项目别用。
方案4:当前页弹窗/抽屉承载详情(补充交互方案)
如果不需要独立的详情页面,想做类似淘宝点击商品弹出半屏详情预览的效果,可以不用做路由跳转:
- 写一个全局的详情弹窗/抽屉组件
- 用状态(简单场景用父子组件传值,复杂场景用Context/轻量状态库)存当前选中的商品数据
- 点击卡片时把当前商品数据存入状态,控制弹窗显示即可
适用场景:作为独立详情页的补充交互,适合快速预览商品信息,缺点是URL不会变化,用户无法直接分享对应商品的详情,刷新页面弹窗会自动关闭。
选型建议:初学者直接从方案1开始练,是实际工作中使用率最高的方案,把动态路由配置、参数传递、数据匹配这一套逻辑跑通,就能覆盖绝大多数列表跳详情的业务需求。
内容的提问来源于stack exchange,提问作者Callmejhed
相关产品推荐
相关产品推荐

