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

React点击表格行获取行列数据并传递给其他组件的实现方法

问题修复方案

你当前代码的核心问题有3个:

  • 非表单元素(td)不存在value属性,你在onClick里取e.target.value永远拿到空值;用innerHTML取值会把单元格里嵌套的<p>标签等冗余内容一起带进来,数据不准
  • 除了team1Back之外,其余的team1Lay、drawBack、drawLay、team2Back、team2Lay要么没绑定点击赋值逻辑,要么取值方式错误
  • 点击赔率单元格后没有同步触发PlaceBett组件的显示开关,数据存完也不会自动弹出组件

修复步骤

  1. 不要从DOM节点取数:表格渲染用的所有数据本来就在传入的data props里,点击的时候直接拿对应下标的数据赋值即可,完全不需要依赖event对象取DOM内容,从根源避免取值错误。
  2. 统一给所有可点击的赔率/数值单元格绑定点击事件,点击时一次性把对应行的BACK、LAY值存入对应state,同时触发PlaceBett组件显示。
  3. 修正state更新方法的命名(原代码里SetDrawLay/SetDrawBack首字母大写不符合React Hook的命名规范,统一改成小驼峰setDrawLay/setDrawBack)。

修复后的核心代码

import { useState } from "react";
import PlaceBett from "./PlaceBett";

const MatchBetTable = ({ data }) => {
  const [showPlaceBet, setShowPlaceBet] = useState(false);

  const [team1Back, setTeam1Back] = useState("");
  const [team1Lay, setTeam1Lay] = useState("");
  const [team2Lay, setTeam2Lay] = useState("");
  const [team2Back, setTeam2Back] = useState("");
  // 修正set方法命名
  const [drawLay, setDrawLay] = useState("");
  const [drawBack, setDrawBack] = useState("");

  // 统一处理赔率点击,直接从传入的data取数,不依赖DOM
  const handleOddsClick = (rowType) => {
    // rowType 对应 1=主队 2=平局 3=客队
    const rowData = data.values[rowType - 1];
    switch(rowType) {
      case 1:
        setTeam1Back(rowData.odds ?? "-");
        setTeam1Lay(rowData.val2 ?? 0);
        break;
      case 2:
        setDrawBack(rowData.odds ?? "-");
        setDrawLay(rowData.val2 ?? 0);
        break;
      case 3:
        setTeam2Back(rowData.odds ?? "-");
        setTeam2Lay(rowData.val2 ?? 0);
        break;
      default:
        break;
    }
    // 赋值后打开投注组件
    setShowPlaceBet(true);
  };

  return (
    <>
      {showPlaceBet && (
        <PlaceBett
          data={data}
          team1Back={team1Back}
          team1Lay={team1Lay}
          team2Back={team2Back}
          team2Lay={team2Lay}
          drawBack={drawBack}
          drawLay={drawLay}
          onClose={() => setShowPlaceBet(false)}
        />
      )}

      <table className="table-auto  mb-4 text-black w-full ">
        <thead className="bg-gray-500 md:p-5 p-1  text-sm">
          <tr>
            <th className="md:p-5 p-1  text-sm">{data.name}</th>
            <th className="md:p-5 p-1  text-sm" colSpan="5"></th>
            <th className="md:p-5 p-1  text-sm">BET DELAY-3 SEC</th>
          </tr>
        </thead>
        <thead>
          <tr className="bg-white md:p-5 p-1  text-sm border border-table_border">
            <th className="md:p-5 p-1  text-sm">MAX 50000</th>
            <th className="md:p-5 p-1  text-sm" colSpan="2"></th>
            <th className="md:p-5 p-1  text-sm  bg-table_row-blue border border-table_border  ">
              BACK <p>(Back)</p>
            </th>
            <th className="md:p-5 p-1  text-sm text-black bg-table_row-cream border border-table_border">
              LAY <p>(lay)</p>
            </th>
            <th className="md:p-5 p-1  text-sm" colSpan="2"></th>
          </tr>
        </thead>
        <tbody>
          {/* 主队行 */}
          <tr className="md:p-5 p-1  text-sm border border-table_border text-center">
            <td className="bg-gray-300 md:p-5 p-1  text-sm">
              {data.values[0].val1 === null ? "-" : data.values[0].val1}
            </td>
            <td className="md:p-5 p-1  text-sm  bg-table_row-blue border border-table_border">
              -<p>(-)</p>
            </td>
            <td className="md:p-5 p-1  text-sm  bg-table_row-blue border border-table_border ">
              -<p>(-)</p>
            </td>
            <td
              className="md:p-5 p-1  text-sm  bg-table_row-blue border border-table_border cursor-pointer hover:opacity-80"
              onClick={() => handleOddsClick(1)}
            >
              {data.values[0].odds === null ? "-" : data.values[0].odds}
            </td>
            <td 
              className="md:p-5 p-1  text-sm  bg-table_row-cream border border-table_border cursor-pointer hover:opacity-80"
              onClick={() => handleOddsClick(1)}
            >
              {data.values[0].val2 === null ? 0 : data.values[0]?.val2}
            </td>
            <td className="md:p-5 p-1  text-sm  bg-table_row-cream border border-table_border ">
              -<p>(-)</p>
            </td>
            <td className="md:p-5 p-1  text-sm  bg-table_row-cream border border-table_border ">
              -<p>(-)</p>
            </td>
          </tr>

          {/* 平局行 */}
          {data.values[1] && (
            <tr className="md:p-5 p-1  text-sm border border-table_border text-center">
              <td className="bg-gray-300 md:p-5 p-1  text-sm">
                {data.values[1]?.val1}
              </td>
              <td className="md:p-5 p-1  text-sm  bg-table_row-blue border border-table_border ">
                -<p>(-)</p>
              </td>
              <td className="md:p-5 p-1  text-sm  bg-table_row-blue border border-table_border ">
                -<p>(-)</p>
              </td>

              <td
                className="md:p-5 p-1 odd:bg-table_row-cream  text-sm  bg-table_row-blue border border-table_border cursor-pointer hover:opacity-80"
                onClick={() => handleOddsClick(2)}
              >
                {data.values[1]?.odds}
              </td>
              <td
                className="md:p-5 p-1  text-sm  bg-table_row-cream border border-table_border cursor-pointer hover:opacity-80"
                onClick={() => handleOddsClick(2)}
              >
                {data.values[1]?.val2 === null ? "0" : data.values[1]?.val2}
              </td>
              <td className="md:p-5 p-1  text-sm  bg-table_row-cream border border-table_border">
                -<p>(-)</p>
              </td>
              <td className="md:p-5 p-1  text-sm  bg-table_row-cream border border-table_border">
                -<p>(-)</p>
              </td>
            </tr>
          )}
          {/* 客队行 */}
          {data?.values[2] && (
            <tr className="md:p-5 p-1  text-sm border border-table_border text-center">
              <td className="bg-gray-300 md:p-5 p-1  text-sm">
                {data?.values[2] && data.values[2]?.val1}
              </td>
              <td className="md:p-5 p-1  text-sm  bg-table_row-blue border border-table_border ">
                -<p>(-)</p>
              </td>
              <td className="md:p-5 p-1  text-sm  bg-table_row-blue border border-table_border ">
                -<p>(-)</p>
              </td>

              <td
                className="md:p-5 p-1 odd:bg-table_row-cream  text-sm  bg-table_row-blue border border-table_border cursor-pointer hover:opacity-80"
                onClick={() => handleOddsClick(3)}
              >
                {data?.values[2] && data.values[2]?.odds}
              </td>
              <td
                className="md:p-5 p-1  text-sm  bg-table_row-cream border border-table_border cursor-pointer hover:opacity-80"
                onClick={() => handleOddsClick(3)}
              >
                {data.values[2]?.val2 === null ? "0" : data.values[2]?.val2}
              </td>
              <td className="md:p-5 p-1  text-sm  bg-table_row-cream border border-table_border">
                -<p>(-)</p>
              </td>
              <td className="md:p-5 p-1  text-sm  bg-table_row-cream border border-table_border">
                -<p>(-)</p>
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </>
  );
};

export default MatchBetTable;

额外说明

  • 给可点击的单元格加了cursor-pointer和hover透明度变化的样式,用户能明确感知这是可点击区域
  • 给PlaceBett组件传入了onClose回调,方便组件内部加关闭按钮控制弹窗隐藏
  • 空值统一用??空值合并运算符处理,逻辑和你原来的判断一致,写法更简洁
  • 不要在调用setXxx之后立刻打印对应state的值,React的state更新是批量异步的,立刻拿不到最新值,要观察值变化可以用useEffect依赖对应state打印。

内容的提问来源于stack exchange,提问作者Vikash kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:06:22