簡體   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