React.js Chakra UI 具有使用状态的多选框

React.js Chakra UI multi-checkbox with use state

大家好,我正在尝试从数组中实现一个 react.js 复选框,并使用 UseState 挂钩将选中的值存储在状态中。我能够显示复选框,但无法选中和取消选中它们。我是新手,来自 Vuejs 背景,习惯了 v-model sytax。这里的任何帮助都会很棒。这是我的代码:

import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useHistory, useLocation } from 'react-router-dom';
import {
  Box,
  Button,
  Checkbox,
  Table,
  Tbody,
  Td,
  Th,
  Thead,
} from '@chakra-ui/react';
import { Form, Input, message } from 'antd';
import styled from 'styled-components';
import useQueryParams from 'utilities/useQueryParams';

import useDelayedServiceCall from '../../../../utilities/useDelayedServiceCall';
interface FormValues {
  query: string;
}

interface SqlQueryRequest {
  query: string;
}

interface SqlQueryResponse {
  column_names: string[];
  rows: string[][];
}
const INITIAL_VALUES: FormValues = {
  query: '',
};
const initArray = [
  'First Name',
  'Middle Name',
  'Last Name',
  'Full Name',
  'Birthday',
  'Address',
  'Email',
  'Phone Number',
  'Ip Address',
  'Aliases',
  'Sign up date',
];
const newArray = initArray.map((item) => ({ value: item, checked: false }));
export default function SqlQueryForm() {
  const [checked, setChecked] = useState(newArray);
  const [array, setArray] = useState(newArray);
  const { t } = useTranslation([
    'actions',
    'common',
    'validations',
    'translation',
  ]);
  function handleCheck(e: any) {
    console.log('e', e);
    if (checked.includes(e.target.value)) {
      const index = checked.indexOf(e.target.value);
      checked.splice(index, 1);
    } else {
      setChecked([
        ...checked,
        {
          value: e.target.value.toString(),
          checked: Boolean(e.target.value.checked),
        },
      ]);
    }
  }
  const query = useQueryParams().get('query')?.trim();
  const history = useHistory();
  const location = useLocation();
  const [{ data, loading }, sqlQuery] = useDelayedServiceCall<
    SqlQueryResponse,
    SqlQueryRequest
  >(
    'franklin',
    'SqlQuery',
    undefined,
    (error) =>
      void message.error(t('common:events.error', { error: error?.message })),
  );
  const vertical = data?.rows[0]?.map((_, columnIndex) =>
    data.rows.map((row) => row[columnIndex]),
  );
  function handleFinish(values: FormValues) {
    const { query: newQuery } = values;
    const path = `${location.pathname}?query=${newQuery}`;
    history.replace(path);
    sqlQuery(values);
  }

  return (
    <>
      <p>
        The PII Reporter tool provides authorized personal access to customer
        PII information. All activity on this API is logged and access is
        reported. Elevated franklin privileges are required to perform the
        underlying actions.
      </p>
      <Box width="60vw">
        <Form>
          <Form.Item>
            <Input type="email" placeholder="email" />
          </Form.Item>
          <Form.Item>
            <Input.TextArea
              disabled={loading}
              rows={5}
              style={{ fontFamily: 'monospace' }}
            />
          </Form.Item>
          {newArray.map((item, index) => (
            <Checkbox
              key={Math.random()}
              {...item}
              onChange={handleCheck}
              isChecked={checked.toString().includes(item.value)}
            >
              {item.value}
            </Checkbox>
          ))}
        </Form>
      </Box>
    </>
  );
}

问题是我没有使用 JSON.parse 复制数组。使用数组时请记住这一点。你需要进行深拷贝...你也可以使用类似 lodash 的东西,然后将 newArray 保存在状态中。