提问人:KaMZaTa 提问时间:3/15/2022 更新时间:3/17/2022 访问量:6753
带有 MUI Autocomplete、FreeSolo 和依赖字段的 React Hook 表单
React Hook Form with MUI Autocomplete, FreeSolo and dependent fields
问:
我正在尝试从这个JSON文件创建(意大利语)依赖字段(这里也是存储库)。我正在使用 React Hook Form v7 和 MUI v5.4.4。我想使用带有 props 的 MUI 自动完成组件实现这 3 个字段,以便让用户插入自定义输入值(如果 JSON 列表中不存在)。ZipCode / City / State
CAP / Città / Provincia
FreeSolo
我试图让它起作用,但它没有。我该如何实现?此外,自动完成组件的验证不起作用。
答:
5赞
knoefel
3/16/2022
#1
您的代码中存在几个问题:
- 你忘了把道具传给你
rules
<Controller />
- 当前选定的值将作为第二个参数传递给 的处理程序
<Autocomplete />
onChange
- 您需要使用 RHF 的方法对这 3 个相关字段的变化做出反应,并相应地过滤其他选择的选项
watch
- 您需要使用而不是用于邮政编码选项的映射,就像数组一样
flatMap
map
option.cap
export default function PersonalDetails() {
const { watch } = useFormContext();
const { postalCode, city, state } = watch("personalDetails");
return (
<Card variant="outlined" sx={{ width: 1 }}>
<CardContent>
<Grid container item spacing={2}>
<Grid item xs={12} lg={3}>
<SelectFree
name="personalDetails.postalCode"
label="ZIP (CAP)"
options={options
.filter((option) =>
city || state
? option.nome === city || option.sigla === state
: option
)
.flatMap((option) => option.cap)}
rules={{ required: "Richiesto" }}
/>
</Grid>
<Grid item xs={12} lg={10}>
<SelectFree
name="personalDetails.city"
label="City (Città)"
options={options
.filter((option) =>
postalCode || state
? option.cap.includes(postalCode) || option.sigla === state
: option
)
.map((option) => option.nome)}
rules={{ required: "Richiesto" }}
/>
</Grid>
<Grid item xs={12} lg={2}>
<SelectFree
name="personalDetails.state"
label="State (Sigla)"
options={options
.filter((option) =>
city || postalCode
? option.nome === city || option.cap.includes(postalCode)
: option
)
.map((option) => option.sigla)}
rules={{ required: "Richiesto" }}
/>
</Grid>
</Grid>
</CardContent>
</Card>
);
}
export default function SelectFree({
name,
rules,
options,
getOptionLabel,
...rest
}) {
const { control } = useFormContext();
return (
<Controller
name={name}
control={control}
rules={rules}
defaultValue={null}
render={({
field: { ref, ...field },
fieldState: { error, invalid }
}) => {
return (
<Autocomplete
{...field}
freeSolo
handleHomeEndKeys
options={options}
getOptionLabel={getOptionLabel}
renderInput={(params) => (
<TextField
{...params}
{...rest}
inputRef={ref}
error={invalid}
helperText={error?.message}
/>
)}
onChange={(e, value) => field.onChange(value)}
onInputChange={(_, data) => {
if (data) field.onChange(data);
}}
/>
);
}}
/>
);
}
更新
由于您有一个非常大的 json 文件,因此有两个选项可以优化性能:
- 通过 -> 的 prop 限制选项的数量,该函数可以配置为设置限制
filterOptions
<Autocomplete />
createFilterOptions
- 在将选项传递给 之前,添加一个钩子用于过滤和映射选项,例如,现在在其他字段 (, , ) 的每次输入更改时,选项将被重新计算
useMemo
<Autocomplete />
firstName
lastName
address
评论
0赞
KaMZaTa
3/16/2022
谢谢,它似乎部分有效。使用“实际”,我收到 ZIP 和 STATE 字段的此错误:30020 如何插入唯一键?comuni.json
Warning: Encountered two children with the same key,
. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
0赞
KaMZaTa
3/17/2022
应该是唯一的键。codiceCatastale
0赞
KaMZaTa
3/17/2022
此外,列表中有很多重复的结果。也许我应该实现某种自定义过滤器?mui.com/components/autocomplete/#custom-filter
0赞
KaMZaTa
3/17/2022
我认为它应该像这样工作,但似乎有点慢。也许我只能显示前 10 个结果。你知道我该如何优化它吗?你觉得怎么样?codesandbox.io/s/empty-architecture-2mqdms
1赞
KaMZaTa
3/17/2022
它现在似乎像一个魅力!谢谢你的努力。
评论