【问题标题】:add or remove a string from an array based on a checkbox基于复选框从数组中添加或删除字符串
【发布时间】:2022-08-20 01:34:52
【问题描述】:

我有一个 nextjs(使用打字稿)前端。我正在尝试创建一个用户创建表单,管理员可以在其中创建其他用户。目标是让表单生成一个简单的用户状态对象,然后将其传递给创建用户文档函数。用户对象非常简单。以下:

const user = {
  name: \"\",
  email: \"\",
  roles: []

}

这些角色让我很头疼。我正在尝试使用 Chakra UI 复选框从角色数组中添加或删除字符串

<CheckboxGroup colorScheme=\"green\">
                <Stack spacing={[1, 5]} direction={[\"column\", \"row\"]}>
                  <Text>roles</Text>
                  <Checkbox
                    value=\"admin\"
                    id=\"admin\"
                    name=\"admin\"
                    onChange={handleCheckBoxChange}
                  >
                    admin
                  </Checkbox>
                  <Checkbox
                    value=\"user\"
                    id=\"user\"
                    name=\"user\"
                    onChange={handleCheckBoxChange}
                  >
                    user
                  </Checkbox>
                </Stack>
              </CheckboxGroup>

我设法让复选框切换为每个复选框的名称分配一个布尔值,但这显然对我没有多大好处。

这是我的 handleCheckBoxChange 函数


  const handleCheckBoxChange = (e: any) => {
    const target = e.target;
    const value = target.type === \"checkbox\" ? target.checked : target.value;
    const name = target.name;
    setRoles({ [name]: value });
    console.log(roles);
  };

从字面上看,我想要的只是当管理员框被选中以将字符串\'admin\'添加到角色中时。当它未选中时,我希望将其删除。用户框也一样。

可能这很容易解决,我只是盯着它太久了

lmk


添加图片

no roles checked - nothing in the array

admin checked, nothing in the array

admin and user checked, array shows \'admin\'

user checked, array shows \'user\'

both checked, array shows \'admin\'


这是我的整个代码块 - 我在 chakra ui 弹出模式中呈现此表单

import {
  Button,
  Checkbox,
  CheckboxGroup,
  Input,
  Modal,
  ModalBody,
  ModalCloseButton,
  ModalContent,
  ModalFooter,
  ModalHeader,
  ModalOverlay,
  Stack,
  Text,
  useDisclosure,
} from \"@chakra-ui/react\";
import { useRouter } from \"next/router\";
import React, { useState } from \"react\";
import { addUser } from \"../../lib/firebase\";

export default function AddUser() {
  const initialRef = React.useRef(null);
  const finalRef = React.useRef(null);
  const { isOpen, onOpen, onClose } = useDisclosure();

  const router = useRouter();
  const customer = router.query.customer;
  const [roles, setRoles] = useState<string[]>([]);

  const [user, setUser] = useState({});

  const handleInputChange = (e: any) => {
    const { name, value } = e.target;
    setUser({ ...user, [name]: value });
  };

  const handleCheckBoxChange = (e: any) => {
    const target = e.target;
    const name = target.name;
    setRoles((currentRoles) =>
      target.checked
        ? [...currentRoles, name]
        : currentRoles.filter((role) => role != name)
    );
    setUser({ ...user, roles: roles });
  };

  const handleSubmit = () => {
    addUser(customer, user);
    onClose();
  };

  console.log(user);

  return (
    <>
      <Button onClick={onOpen}>add user</Button>

      <Modal
        isOpen={isOpen}
        onClose={() => {
          onClose();
          setUser([]);
        }}
        initialFocusRef={initialRef}
        finalFocusRef={finalRef}
      >
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Modal Title</ModalHeader>
          <ModalCloseButton />
          <ModalBody>
            <form onSubmit={handleSubmit}>
              <Input
                ref={initialRef}
                name=\"name\"
                placeholder=\"name\"
                onChange={handleInputChange}
              />
              <Input
                name=\"email\"
                placeholder=\"email\"
                onChange={handleInputChange}
              />
              <CheckboxGroup colorScheme=\"green\">
                <Stack spacing={[1, 5]} direction={[\"column\", \"row\"]}>
                  <Text>roles</Text>
                  <Checkbox
                    name=\"admin\"
                    value=\"admin\"
                    onChange={handleCheckBoxChange}
                  >
                    admin
                  </Checkbox>
                  <Checkbox
                    name=\"user\"
                    value=\"user\"
                    onChange={handleCheckBoxChange}
                  >
                    user
                  </Checkbox>
                </Stack>
              </CheckboxGroup>
            </form>
          </ModalBody>

          <ModalFooter>
            <Button
              colorScheme=\"blue\"
              mr={3}
              type=\"submit\"
              onClick={handleSubmit}
            >
              submit
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </>
  );
}

    标签: reactjs typescript next.js chakra-ui


    【解决方案1】:

    一种选择是像您一样根据名称更新状态,但将函数传递给处理添加/删除项目的状态设置器,即:

    const handleCheckBoxChange = (e: any) => {
      const target = e.target;
      const name = target.name;
      setRoles((currentRoles) =>
        target.checked
          ? [...currentRoles, name]
          : currentRoles.filter((role) => role !== name)
      );
    };
    

    将函数传递给状态设置器时,该函数将传递现有状态并预期返回更新后的状态。通过这种方式,您将获得当前选定的角色,并返回它的副本并添加或删除所选项目,具体取决于复选框是否被选中。

    【讨论】:

    • 感谢您的建议..我将该代码放入其中并从数组中添加和删除字符串,但是在检查时将其删除并在未选中时添加+其他一些奇怪的事情..我会在我的主要帖子中添加一些图片
    • 你能分享你用来评估当前状态的代码吗?这是一个按预期工作的简单代码框:codesandbox.io/s/checkboxes-to-array-state-67rzvo?file=/src/…
    • 刚刚用整段代码更新了帖子
    • 您的代码中还有一个问题 - 设置状态不是同步的,因此在 setRoles 之后立即调用 setUser 将不会获得 roles 的更新状态。使用您当前的代码,roles 状态将获得正确的更新数组,但 user 状态中的 roles 字段将获得以前的版本。您必须在角色setState 函数之外创建更新的角色数组并将其传递给两者,或者您可以使用useEffectroles 状态更改时更新您的user 状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-13
    • 2013-07-04
    • 2014-09-07
    相关资源
    最近更新 更多