繁体   English   中英

如何使用 Chakra UI 使复选框工作

[英]How to make checkbox work using Chakra UI

我想做一个复选框功能,您单击父复选框并检查所有子复选框。 但您也可以选择单个复选框。 我正在尝试使用 Chakra UI 执行此操作,但在文档中他们仅使用两个复选框来执行此操作。 在我的情况下,我使用 map 进行迭代,所以出现的问题是我只能检查它们,但我不能取消选中单个复选框。 我将如何解决这个问题?

 import NextLink from 'next/link';
import { useState } from 'react';
import { queryClient } from '../../services/queryClient';
import { api } from '../../services/api';

export default function UserList() {
  const [page, setPage] = useState(1);
  const [checkedItems, setCheckedItems] = useState([false, false]);

  const allChecked = checkedItems.every(Boolean);
  const isIndeterminate = checkedItems.some(Boolean) && !allChecked;

  const { data, isLoading, isFetching, error } = useUsers(page);

  async function handlePrefetchUser(userId: string) {
    await queryClient.prefetchQuery(
      ['user', userId],
      async () => {
        const response = await api.get(`users/${userId}`);

        return response.data;
      },
      {
        staleTime: 1000 * 60 * 10,
      }
    );
  }

  return (
    <Box>
      <Header />

      <Flex my="6" maxWidth={1480} mx="auto" px="6">
        <Sidebar />

        <Box flex="1" borderRadius={8} bg="gray.800" p="8">
          <Flex mb="8" justify="space-between" align="center">
            <Heading size="lg" fontWeight="normal">
              Alunos
              {!isLoading && isFetching && (
                <Spinner size="sm" color="gray.500" ml="4" />
              )}
            </Heading>

            <HStack spacing={4}>
              <NextLink href="/users/create" passHref>
                <Button as="a" size="sm" fontSize="sm" colorScheme="orange">
                  <Icon as={RiAddLine} fontSize="20" />
                </Button>
              </NextLink>

              <NotificationModal />

              <Button
                as="a"
                size="sm"
                fontSize="sm"
                colorScheme="green"
                cursor="pointer"
              >
                <Icon as={CgImport} />
              </Button>
            </HStack>
          </Flex>

          {isLoading ? (
            <Flex justify="center" align="center">
              <Spinner />
            </Flex>
          ) : error ? (
            <Flex justify="center">
              <Text>Falha ao obter dados dos usuários.</Text>
            </Flex>
          ) : (
            <>
              <Table colorScheme="whiteAlpha">
                <Thead>
                  <Tr>
                    <Th px={['4', '4', '6']} color="gray.300" w="8">
                      <Checkbox
                        colorScheme="orange"
                        isChecked={allChecked}
                        isIndeterminate={isIndeterminate}
                        onChange={(e) =>
                          setCheckedItems([e.target.checked, e.target.checked])
                        }
                      />
                    </Th>

                    <Th>Usuários</Th>
                    <Th>Ações</Th>
                    <Th w="8"></Th>
                  </Tr>
                </Thead>

                <Tbody>
                  {data.users.map((user) => (
                    <Tr key={user.id}>
                      <Td px={['4', '4', '6']}>
                        <Checkbox
                          colorScheme="orange"
                          isChecked={checkedItems[0]}
                          onChange={(e) =>
                            setCheckedItems([e.target.checked, checkedItems[1]])
                          }
                        />
                      </Td>

                      <Td>
                        <Box>
                          <Link
                            color="orange.400"
                            onMouseEnter={() => handlePrefetchUser(user.id)}
                          >
                            <Text fontWeight="bold">{user.name}</Text>
                          </Link>
                          <Text fontSize="sm" color="gray.300">
                            {user.email}
                          </Text>
                        </Box>
                      </Td>

                      <Td>
                        <Box cursor="pointer">
                          <HStack spacing={4}>
                            <Text
                              color="orange.400"
                              _hover={{
                                color: 'orange.500',
                              }}
                            >
                              Editar
                            </Text>
                            <Text
                              color="gray.300"
                              _hover={{
                                color: 'gray.500',
                              }}
                            >
                              Excluir
                            </Text>
                          </HStack>
                        </Box>
                      </Td>
                    </Tr>
                  ))}
                </Tbody>
              </Table>

              <Pagination
                totalCountOfRegisters={data.totalCount}
                currentPage={page}
                onPageChange={setPage}
              />
            </>
          )}
        </Box>
      </Flex>
    </Box>
  );
}

以下是如何管理未知数量的子复选框的简化示例:

https://codesandbox.io/s/stupefied-currying-s3r7dr?file=/src/App.js

对于您的用例,将复选框和复选框状态移动到仅在加载用户后才呈现的子组件中可能会有所帮助。 这将允许您使用正确数量的用户设置初始复选框状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM