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

React表格点击单行仅展示对应AutoShopPriceExpand组件的方法

解决React表格单行独立展开/收起组件的问题

你当前的问题是用了全局的isOpen状态,导致点击任何一行的按钮都会触发所有行的展开/收起。要实现单行独立控制,需要把状态改成记录当前展开行的唯一标识,具体修改如下:

关键修改点

  • 将全局布尔状态isOpen改为存储当前展开行的唯一ID(或其他唯一字段,比如数据里的主键)
  • 调整切换函数,接收当前行的标识,判断是否要展开/收起该行
  • 修改展开组件的渲染条件,只匹配当前行的标识时才显示
  • 给map生成的元素设置唯一key(不能用固定字符串,否则React无法正确追踪列表项)

修改后的完整代码

import { Box, Text, Table, Tbody, Td, Th, Thead, Tr, Button } from '@chakra-ui/react';
import { AutoShopPriceExpand } from './autoShopPriceExpand';
import { useState, Fragment } from 'react';

export const AutoShopPricesList = ({ filteredAutoShopPricesLists }: { filteredAutoShopPricesLists: any }) => {
    // 用null初始化,存储当前展开行的唯一标识(假设你的数据有id字段,没有的话换其他唯一字段)
    const [expandedRowId, setExpandedRowId] = useState<number | null>(null);

    // 接收当前行的id,切换展开状态
    function toggleRow(id: number) {
        setExpandedRowId(prevId => prevId === id ? null : id);
    }

    return (
        <Box py={1}>
            <Table variant='striped'>
                <Thead>
                    <Tr>
                        <Th>Vehicle</Th>
                        <Th>Service</Th>
                        <Th isNumeric>Price</Th>
                        <Th>操作</Th>
                    </Tr>
                </Thead>
                <Tbody>
                    {filteredAutoShopPricesLists.map((autoshop: any) => {
                        // 假设autoshop有id作为唯一标识,没有的话可以用组合字段比如`${autoshop.car_id}-${autoshop.service_id}`
                        const isRowExpanded = expandedRowId === autoshop.id;
                        return (
                            <Fragment key={autoshop.id}>
                                <Tr>
                                    <Td>{autoshop.car_year} {autoshop.car_make} {autoshop.car_model} <br/> <Text color='gray' fontSize='sm'> {autoshop.car_trim} </Text></Td>
                                    <Td>{autoshop.service} <br/>  <Text color='gray' fontSize='sm'>{autoshop.date_of_quote} </Text> </Td>
                                    <Td isNumeric> ${autoshop.service_price} <br/>  <Text color='gray' fontSize='sm'>{autoshop.source_of_price} </Text></Td>
                                    <Td>
                                        {/* 点击时传入当前行的id */}
                                        <Button onClick={() => toggleRow(autoshop.id)}>
                                            {isRowExpanded ? '收起详情' : '展开详情'}
                                        </Button>
                                    </Td>
                                </Tr>
                                {/* 只有当前行展开时才显示组件 */}
                                {isRowExpanded && <AutoShopPriceExpand details={autoshop}/>}
                            </Fragment>
                        );
                    })}
                </Tbody> 
            </Table>  
        </Box>
    );
};

额外说明

  1. 如果你的autoshop数据没有单独的id字段,可以用多个字段组合成唯一标识,比如${autoshop.car_year}-${autoshop.car_make}-${autoshop.service},确保每个行的标识唯一即可。
  2. 把原生button换成了Chakra UI的Button组件,保持样式统一,如果你想用原生按钮也可以,但建议和项目UI库保持一致。
  3. 按钮文字根据展开状态动态切换,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:10:57