繁体   English   中英

带有 react-form-hook 验证值的 Material UI 自动完成未正确更改

[英]Material UI autocomplete with react-form-hook validation value is not changing properly

我正在尝试实现多选 Mui 自动完成功能。

每当用户选择一个选项时,我希望芯片组件显示在下面。

我正在使用 react-form-hook 来检查验证。 categories字段是一个数组,我希望它至少有一个项目。

问题是当我删除一个芯片时,值没有正确更新。 我正在使用反应状态来跟踪 selectedItems,以便我可以显示芯片组件。

当我删除芯片时,它会从 selectedItem 状态中删除,但 Controller 的实际值不会改变。

请检查我的代码,并给我一些反馈。 谢谢你们!!

mui_autocomplete

import React, { useEffect, useState } from 'react';
import { Autocomplete, Chip, FormControl, FormLabel, Stack, TextField } from '@mui/material';
import { Controller } from 'react-hook-form';
import CloseIcon from '@mui/icons-material/Close';

export default function FormAutoComplete({ name, control, label, error, ...props }) {
  const [selectedItems, setSelectedItems] = useState([]);

  const selectedItemChip = selectedItems.map((item) => {
    return (
      <Chip
        key={item}
        label={item}
        deleteIcon={<CloseIcon />}
        onDelete={() => {
          setSelectedItems((prev) => prev.filter((entry) => entry !== item));
        }}
      />
    );
  });

  return (
    <FormControl fullWidth>
      <FormLabel>{label}</FormLabel>
      <Controller
        name={name}
        control={control}
        render={({ field: { onChange, value } }) => (
          <Autocomplete
            multiple
            filterSelectedOptions
            options={options}
            getOptionLabel={(option) => option}
            renderTags={() => {}}
            value={selectedItems}
            onChange={(e, newValue) => {
              const addedItem = newValue[newValue.length - 1];
              setSelectedItems((prev) => [...prev, addedItem]);
              onChange(selectedItems);
              return selectedItems;
            }}
            renderInput={(params) => (
              <TextField
                {...params}
                {...props}
                error={!!error}
                helperText={error && error.message}
              />
            )}
          />
        )}
      />
      <Stack direction="row" marginTop={2} gap={1} flexWrap="wrap">
        {selectedItemChip}
      </Stack>
    </FormControl>
  );
}

export const options = [
  'Building Materials',
  'Tools',
  'Decor & Furniture',
  'Bath',
  'Doors & Windows',
  'Cleaning',
  'Electrical',
  'Heating & Cooling',
  'Plumbing',
  'Hardware',
  'Kitchen',
  'Lawn & Garden',
  'Lighting & Fans',
];

沙盒

删除芯片后,react-hook-form 不会更新为最新值。 因此,提交表单时,会记录旧数据。

  1. 无需在状态变量中跟踪selectedItems 您可以使用useWatch钩子从 react-hook-form 获取最新值
  2. 使用setValue更新formState中的值

通过这些更改,您的FormAutoComplete组件应如下所示

export default function FormAutoComplete({
  name,
  control,
  label,
  error,
  setValue, // Pass this prop from parent component. Can be destructured from useForm hook
  ...props
}) {
  // const [selectedItems, setSelectedItems] = useState([]);
  const selectedItems = useWatch({control,name}) // import useWatch from react-hook-form
  const selectedItemChip = selectedItems.map((item) => {
    return (
      <Chip
        key={item}
        label={item}
        deleteIcon={<CloseIcon />}
        onDelete={() => {
          // setSelectedItems((prev) => [...prev.filter((entry) => entry !== item)]);
        setValue(name,selectedItems.filter((entry) => entry !== item))
        }}
      />
    );
  });

  return (
    <FormControl fullWidth>
      <FormLabel>{label}</FormLabel>
      <Controller
        name={name}
        control={control}
        render={({ field: { onChange, value } }) => (
          <Autocomplete
            multiple
            filterSelectedOptions
            options={options}
            getOptionLabel={(option) => option}
            renderTags={() => {}}
           // value={selectedItems}
            value={value}
            onChange={(e, newValue) => {
              // setSelectedItems(newValue);
              onChange(newValue);
            }}
            renderInput={(params) => (
              <TextField
                {...params}
                {...props}
                error={!!error}
                helperText={error && error.message}
              />
            )}
          />
        )}
      />
      <Stack direction="row" marginTop={2} gap={1} flexWrap="wrap">
        {selectedItemChip}
      </Stack>
    </FormControl>
  );
}

文档:

暂无
暂无

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

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