[英]Material UI autocomplete with react-form-hook validation value is not changing properly
I am trying to implement multi-select Mui autocomplete.我正在尝试实现多选 Mui 自动完成功能。
Whenever user selects an option, I want Chip component to be displayed underneath.每当用户选择一个选项时,我希望芯片组件显示在下面。
I am using react-form-hook to check validation.我正在使用 react-form-hook 来检查验证。
categories
field is an array, and I want it to have at least one item. categories
字段是一个数组,我希望它至少有一个项目。
Problem is when I delete a chip, the value does not update properly.问题是当我删除一个芯片时,值没有正确更新。 I am using react state to keep track of selectedItems so I can display Chip component.
我正在使用反应状态来跟踪 selectedItems,以便我可以显示芯片组件。
When I delete the chip, it is deleted from selectedItem state, but actual value from Controller does not change.当我删除芯片时,它会从 selectedItem 状态中删除,但 Controller 的实际值不会改变。
Please review my code, and give me some feedbacks.请检查我的代码,并给我一些反馈。 Thank you all!!
谢谢你们!!
mui_autocomplete 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',
];
Once chip is deleted, react-hook-form is not updated with latest value.删除芯片后,react-hook-form 不会更新为最新值。 So, when form is submitted, old data is logged.
因此,提交表单时,会记录旧数据。
selectedItems
in a state variable.selectedItems
。 You can use useWatch
hook to get latest value from react-hook-formuseWatch
钩子从 react-hook-form 获取最新值setValue
to update value in formState
setValue
更新formState
中的值With these changes your FormAutoComplete
component should look like this通过这些更改,您的
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>
);
}
Documentation :文档:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.