我一直在开发一个简单的表格,用户可以单击每一行并将其展开。
我已经使用切换使其工作,当前切换正在工作,但问题是当我单击时所有行都会展开我正在努力寻找一种解决方案,以便在用户单击该行时一次只展开一行
有人可以帮我解决这个问题吗?请在下面找到我的代码
import {
Table,
Stack,
Paper,
Title,
LoadingOverlay,
Collapse
} from '@mantine/core'
import { ApiData, useApi } from '@venturi-io/frontend/src/utils/useApi'
import React, { useCallback, useEffect } from 'react'
import { getEmnify } from '@venturi-io/api/src/launch/emnify'
import { useUserStore } from 'src/stores'
import NoData from 'src/Components/NoData'
import { useDisclosure } from '@mantine/hooks'
export default function Emnify () {
const emnify = useApi(getEmnify)
const token = useUserStore(state => state.user['X-Auth-Token'])
const loadEmnify = useCallback((page: number, size: number) => {
void emnify.fetch({ page, size }, token)
}, [])
const [opened, { toggle }] = useDisclosure(false)
function EmnifyViewRows ({ items: emnifyViews }: ApiData<typeof getEmnify>): React.ReactNode {
return emnifyViews
.map(({
id, eventId, description, timestamp, createdOn, eventTypeId, eventTypeDescription,
eventSourceId, eventSourceDescription, eventSeverityId, eventSeverityDescription, orgId,
endpointId, simId, imsi, detail
}) => (
<>
<tr key={id} onClick={toggle}>
<td>{id}</td>
<td>{eventId}</td>
<td>{eventTypeId}</td>
<td>{eventTypeDescription}</td>
<td>{timestamp}</td>
<td>{createdOn}</td>
<td>{description}</td>
</tr>
<Collapse in={opened} transitionDuration={500} transitionTimingFunction="linear" key={id}>
<thead>
<tr>
<th>Event Source Id</th>
<th>Event Source Description</th>
<th>Event Severity Id</th>
<th>Event Severity Description</th>
<th>Org Id</th>
<th>Endpoint Id</th>
<th>Sim Id</th>
<th>Imsi</th>
<th>Detail</th>
</tr>
</thead>
<tr>
<td>{eventSourceId}</td>
<td>{eventSourceDescription}</td>
<td>{eventSeverityId}</td>
<td>{eventSeverityDescription}</td>
<td>{orgId}</td>
<td>{endpointId}</td>
<td>{simId}</td>
<td>{imsi}</td>
<td>{detail}</td>
</tr>
</Collapse>
</>
))
}
useEffect(() => {
loadEmnify(1, 20)
}, [])
const nothing = useCallback(() => <NoData colSpan={5} />, [])
return (
<Stack>
<Paper p="sm" sx={() => ({ position: 'relative' })}>
<Title order={3}>
Emnify
</Title>
<LoadingOverlay visible={emnify.loading} />
<Table striped mt="sm">
<thead>
<tr>
<th>ID</th>
<th>Event ID</th>
<th>Event Type Id</th>
<th>Event Type Description</th>
<th>Timestamp</th>
<th>Created On</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{emnify
.data
.caseOf({
Nothing: nothing,
Just: EmnifyViewRows
})}
</tbody>
</Table>
</Paper>
</Stack>
)
}
看来您是初学者。其实你的代码不是很优雅,但是这是一个学习的过程。我们来谈谈你提出的问题吧。
您应该使用
Array
或 Set
来存储展开行的 id:
const [opened, setOpened] = useState(new Set());
处理点击行:
() => {
setOpened((prev) => {
if (prev.has(id)) {
prev.delete(id);
} else {
prev.add(id);
}
return new Set(prev);
});
};
判断该行是否展开:
<Collapse in={opened.has(id)} ...