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

React中如何结合onClick按钮使用useParams跳转并按ID展示数据

问题根因

你代码里存在两个核心问题导致出现全量数据展示的情况:

  1. ID类型不匹配:useParams() 拿到的路由参数id是字符串类型,若接口返回的item.id为数字类型,全等判断item.id === id会直接返回false,导致过滤逻辑失效
  2. 账单详情区域未加过滤:你仅在顶部explore-container区域加了ID过滤逻辑,下方核心账单展示的bills-container > .item-list区域直接对全量items.items做了遍历,所以会渲染所有接口返回的数据

修复步骤

直接修改Billing.js代码即可:

  1. 提前统一ID类型并过滤出当前要展示的账单数据,避免重复写过滤逻辑
  2. 替换全量遍历逻辑,只渲染过滤后的单条账单数据

修改后的核心代码

import React, { useState } from "react";
import "./Bill.css";
import { Link, useParams } from "react-router-dom";
import { connect } from "react-redux";

function BillList({ items }) {
  const [counter, setCounter] = useState(1);
  // 从路由取id并转成数字,和接口返回的id类型保持一致
  const { id } = useParams();
  const targetId = Number(id);
  // 提前过滤出当前要展示的单条账单
  const currentBill = items?.items?.find(item => item.id === targetId);

  function Display(props) {
    return <label style={{ marginLeft: ".5rem" }}>{props.message}</label>;
  }

  // 加个loading/空状态判断,避免数据没加载完报错
  if (!currentBill) return <div>加载中...</div>

  return (
    <div className="bills">
      <div className="explore-container">
        {/* 这里不用再遍历了,直接用currentBill */}
        <div className="item-list" key={currentBill.id}>
          <h2>Title: {currentBill.title}</h2>
          <h4>price: {currentBill.price}</h4>
        </div>
      </div>
      <div
        className="main-title"
        style={{
          textAlign: "center",
          justifyContent: "center",
          alignItems: "center",
          fontSize: 14,
        }}
      >
        <h1>Bakery</h1>
        <h1>Company Gbr</h1>
        <h1>Oranienburger Straße 120</h1>
        <h1>10119 Berlin</h1>
      </div>

      <div className="bills-container">
        <div></div>

        {/* pass in the details  */}
         <div className="item-list">
          {/* 这里也不用遍历全量数据,直接用currentBill渲染 */}
          <React.Fragment key={currentBill.id}>
            <div className="bill-time">
              <div className="bill">
                <h4>
                  {" "}
                  <strong>Bill: </strong>
                  {currentBill.billNumber}
                </h4>
              </div>

              <div className="time">
                <h4>
                  {" "}
                  <strong>Time: </strong>
                  {currentBill.created_datetime}
                </h4>
              </div>
            </div>
            ----------------------------------
            ----------------------------------
            ---------------------------------- --------------------
            {/* Counter  */}
             <div className="price-total">
              <div className="title">
                <h3>
                  {" "}
                  <strong>Title: </strong>
                  {currentBill.title}
                </h3>
                <div className="counter">
                  <strong>
                    <Display message={counter} />x
                  </strong>
                </div>
              </div>

              <div className="increase">
                <button onClick={() => setCounter(counter + 1)}>+</button>
              </div>
              <div className="decrease">
                <button onClick={() => setCounter(Math.max(1, counter - 1))}>-</button>
              </div>

              {/* Price and total */}

               <div className="price">
                <h4>
                  <strong>Price: {parseFloat(currentBill.price)}€</strong>
                </h4>
              </div>

              <div className="total">
                <h4>Total: {parseFloat(currentBill.price * counter)}€</h4>
              </div>
            </div>
          </React.Fragment>
        </div>  
      </div>

      <div className="button-path">
        <Link to="/items">
          <div className="button">
            <button className="main-button">Analyse Receipt</button>
          </div>
        </Link>
      </div>
    </div>
  );
}

const mapStateToProps = (state) => {
  return {
    items: state.items,
  };
};

export default connect(mapStateToProps)(BillList);

额外优化点

  • 给减号按钮加了最小值限制Math.max(1, counter - 1),避免数量出现负数
  • 移除了没用的冗余代码:比如组件末尾多余的<Switch>、未使用的getItems引入和映射逻辑
  • 加了空状态判断,避免数据还没加载完成时报错

内容的提问来源于stack exchange,提问作者karim Salim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 13:48:02