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

React中点击购买历史跳转详情页向组件传递props失败问题求助

问题核心原因

你当前的传参逻辑存在两个核心错误:

  1. 路由注册写法不符合React Router规范,路由渲染的PurchaseHistoryItem和你在列表中循环的PurchaseHistoryItem是完全独立的两个实例,自然拿不到你循环时传入的history prop
  2. 跳转时仅传递了记录ID到URL,没有将完整的记录数据传递给详情页组件,且列表页直接将PurchaseHistoryItem作为列表条目渲染,不符合跳转逻辑

解决方法

提供两种可行方案,可根据业务需求选择:

方案一:URL参数+请求详情(最推荐,刷新页面数据不丢失)

此方案适配绝大多数业务场景,数据可靠性最高

  1. 修正路由注册(以React Router v6为例)
import { Routes, Route } from 'react-router-dom'
// 其他导入省略

<Routes>
  {/* 其余路由保持不变 */}
  <Route path="user/history/:id" element={<PurchaseHistoryItem />} />
</Routes>

如果使用React Router v5,写法为<Route path="user/history/:id" component={PurchaseHistoryItem} />

  1. 调整PurchaseHistoryPage列表页逻辑
    不要直接在列表中渲染PurchaseHistoryItem组件,改为渲染可跳转的条目:
const PurchaseHistoryPage = (props) => {
  const classes = useStyles()
  const [history, setHistory] = useState([])

  useEffect(() => {
    const user = getUser()
    getPurchaseHistory(
      "/user/list/purchase-history/" + user.userId,
      user.token
    ).then((data) => {
      // 存储原始数据,不要直接存组件
      setHistory(data)
    })
  }, [])

  return (
    <>
      <Grid container spacing={3}>
        <Grid item xs={2}>
          <Box pt={0.5}>
            <Link to="/user">
              <ArrowBackIcon className={classes.backSize} />
            </Link>
          </Box>
        </Grid>
        <Grid item xs={10}>
          <Typography variant="h6">Purchase History</Typography>
        </Grid>
      </Grid>
      <Box pt={5}></Box>
      <div>
        {/* 循环渲染可跳转的列表条目 */}
        {history.map(item => (
          <Link 
            key={item._id}
            to={`/user/history/${item._id}`} 
            className={classes.decoration}
          >
            {/* 此处写列表需要展示的摘要信息,例如下单时间、店铺名称 */}
            <p>{item.shop.name} | {item.payTime}</p>
          </Link>
        ))}
      </div>
    </>
  )
}
  1. 调整PurchaseHistoryItem详情页逻辑
    从URL获取ID后调用后台详情接口获取完整数据:
import React, { useEffect, useState } from "react"
import { useParams } from 'react-router-dom'
// 导入你的详情接口请求方法、getUser工具

const PurchaseHistoryItem = () => {
  // 从路由参数获取记录ID
  const { id } = useParams()
  const [detail, setDetail] = useState(null)

  useEffect(() => {
    const user = getUser()
    // 调用详情接口获取对应ID的购买记录
    getPurchaseDetail(`/user/purchase-history/${id}`, user.token)
      .then(res => setDetail(res))
  }, [id])

  // 加载态兜底
  if (!detail) return <p>加载中...</p>

  console.log(detail.shop.name)
  return (
    <>
      <p>店铺名称:{detail.shop.name}</p>
      {/* 其余详情展示逻辑 */}
    </>
  )
}

export default PurchaseHistoryItem

方案二:路由状态传参(无需额外请求,刷新页面数据丢失)

如果详情数据不需要持久化、且不想额外调用详情接口,可以用Link的state属性传递完整数据

  1. 调整列表页Link写法,添加state参数:
<Link 
  to={`/user/history/${item._id}`} 
  state={{ history: item }}
  className={classes.decoration}
>
  条目内容
</Link>
  1. 详情页从路由状态获取数据:
import React from "react"
import { useLocation } from 'react-router-dom'

const PurchaseHistoryItem = () => {
  const location = useLocation()
  const history = location.state?.history

  // 兜底逻辑,避免刷新后数据丢失
  if (!history) return <p>数据不存在,请返回列表重试</p>

  console.log(history.shop.name)
  return (
    <>
      <p>test</p>
    </>
  )
}

export default PurchaseHistoryItem

路由注册逻辑和方案一一致即可。


内容的提问来源于stack exchange,提问作者Pinky Promise

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 19:54:06