如何使用 mantine 框架一次仅切换一行并做出反应

问题描述 投票:0回答:1

我一直在开发一个简单的表格,用户可以单击每一行并将其展开。

我已经使用切换使其工作,当前切换正在工作,但问题是当我单击时所有行都会展开我正在努力寻找一种解决方案,以便在用户单击该行时一次只展开一行

有人可以帮我解决这个问题吗?请在下面找到我的代码

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>
  )
}

reactjs typescript toggle hook mantine
1个回答
0
投票

看来您是初学者。其实你的代码不是很优雅,但是这是一个学习的过程。我们来谈谈你提出的问题吧。

您应该使用

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)} ...
© www.soinside.com 2019 - 2024. All rights reserved.