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

React Table点击Details按钮展示对应行额外详情的实现方案问询

实现方案

你需要通过父子组件传值的方式打通三个组件的数据通信,具体修改如下:

1. 修改 App.js

在App组件的state中存储选中的条目数据,同时把更新选中状态的方法传递给Table组件,把选中的数据传递给Details组件:

import './App.css';
import Details from './components/Details'
import Table from './components/Table';
import React, { Component } from 'react';

class App extends Component {
  state = {
    selectedItem: null // 存储当前选中的条目详情
  }

  // 用箭头函数避免this绑定问题
  handleSelectItem = (item) => {
    this.setState({
      selectedItem: item
    })
  }

  render() {
    return (
      <>
        <Table onSelectItem={this.handleSelectItem} />
        <Details selectedItem={this.state.selectedItem} />
      </>
    )}
}

export default App;

2. 修改 Table.js

接收父组件传递的onSelectItem方法,给Details按钮绑定点击事件,把当前行的原始数据传递给父组件:

import React, { useMemo } from "react";
import Data from "../sample.json"
import { useTable, useSortBy, usePagination } from 'react-table'
import { Columns } from './Columns'
import './Table.css'

// 提前给数据加ID,避免每次渲染重复执行
Data.forEach((item, i) => {
  item.id = i + 1
})

function Table({ onSelectItem }) {
  // 重写Link列的Cell,绑定点击事件
  const columns = useMemo(() => {
    const cols = [...Columns]
    const linkColumnIndex = cols.findIndex(col => col.Header === 'Link')
    cols[linkColumnIndex].Cell = props => <button onClick={() => onSelectItem(props.row.original)}>Details</button>
    return cols
  }, [onSelectItem])

  const data = useMemo(() => Data, [])

  const { 
    getTableProps, 
    getTableBodyProps,
    headerGroups,
    page,
    nextPage,
    previousPage,
    canNextPage,
    canPreviousPage,
    pageOptions,
    state,
    prepareRow, 
  } = useTable(
    {columns, data, initialState: {pageSize: 5}},
    useSortBy,
    usePagination)
  
    const { pageIndex } = state

  return (
    <>
      <table {...getTableProps()}>
      <thead>
        {headerGroups.map(headerGroup => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map(column => (
              <th {...column.getHeaderProps(column.getSortByToggleProps())}>
                {column.render('Header')}
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {page.map(row => {
          prepareRow(row)
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map(cell => {
                return (
                  <td {...cell.getCellProps()}>
                    {cell.render('Cell')}
                  </td>
                )})}
            </tr>
          )})}
      </tbody>
      </table>
      <div>
        <center>
        <span>
          Page{' '}{pageIndex + 1} of {pageOptions.length}{' '}
        </span>
        <button 
          onClick={() => previousPage()} 
          disabled={!canPreviousPage}>
            Previous
        </button>
        <button 
          onClick={() => nextPage()}
          disabled={!canNextPage}>
            Next
          </button>
          </center>
      </div>
    </>
  )
}

export default Table;

注:这里没有修改原有的Columns.js文件,而是在Table组件内部重写了Link列的渲染逻辑,不需要改动原有列配置。

3. 修改 Details.js

接收父组件传递的selectedItem,没有选中条目时不渲染,选中时只渲染对应条目的内容:

import React from 'react';

function Details({ selectedItem }) {
  // 没有选中条目直接返回null不渲染
  if (!selectedItem) return null

  return (
    <div className="item">
      <div className="itemRow1">
        <div>
          <h4>{ selectedItem.Payee.Name }</h4>
          <div>{ selectedItem.Payee.Phone }</div>
          <div>{ selectedItem.Payee.Address.Address1 }</div>
          <div>{ selectedItem.Payee.Address.Address2 }</div>
          <div>{ selectedItem.Payee.Address.City }</div>
          <div>{ selectedItem.Payee.Address.StateOrProvince }</div>
          <div>{ selectedItem.Payee.Address.Country }</div>
          <div>{ selectedItem.Payee.Address.PostalCode }</div>
          <br/>
          <div>{ selectedItem.Payee.Attention} </div>
          <div>{ selectedItem.Payee.SubmissionDate }</div>
        </div>
        <div>
          <h4>Payment Information</h4>
          <div>{ selectedItem.Payment.PAN }</div>
          <div>{ selectedItem.Payment.CVV }</div>
          <div>{ selectedItem.Payment.Exp }</div>
        </div>
        <div>
          <h4>Remittance</h4>
          <div>{ selectedItem.Remittance.map(payor => {
            return(
              <div className="payor">
                <div>{ payor.PayorName }</div>
                <div>{ payor.PayorId }</div>
                <div>{ payor.InvoiceNo }</div>
                <div>{ payor.Amount }</div>
                <br/>
              </div>
            )})}
          </div>
        </div>
      </div>
      <div>
        {selectedItem.Remittance.map(payor => {
          return (
            <div className="description">
              {payor.Description}
            </div>
          )})}
      </div>
    </div> 
  );
}

export default Details;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 22:15:03