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
相关产品推荐
相关产品推荐

