如何在提交表单后清除Material-UI Autocomplete组件的选中值?
解决React Hook Form结合Material-UI Autocomplete提交后无法清除选中值的问题
问题根源
你当前的实现同时维护了React Hook Form(RHF)的表单状态和自定义的form状态,导致状态冗余且不同步:
- Autocomplete的
value依赖自定义form.tags过滤后的结果 - 提交时调用
reset({})只会更新RHF内部状态,不会同步更新你的form状态 - 双状态管理导致重置后Autocomplete依然显示旧选中值
修复方案
- 移除自定义
form状态中与RHF重复的字段,仅保留需手动处理的字段(如image,用于文件上传) - 让Autocomplete完全由RHF的
Controller控制,直接使用field.value匹配选中项 - 提交时从RHF返回的
data中获取所有字段值,包括tags - 重置时同步更新所有相关状态
修改后的完整代码
type tagsData = { id: number | null; title: string; }; const schema = yup.object({ title: yup.string().required(), isPublished: yup.boolean().notRequired(), body: yup.string().notRequired(), image: yup.string().required(), userId: yup.string().required(), tags: yup.array().min(1, "انتخاب حداقل یک تگ اجباری است"), categoryId: yup.string().required(), }); const AddEditPost = function ({ typeOperation, onAdd, onEdit, editFormData, }: any) { const initialFormValues = { isPublished: editFormData?.isPublished || true, title: editFormData?.title || "", body: editFormData?.body || "", image: editFormData?.image || "", userId: editFormData?.userId || "da154cf1-aacb-46cf-a407-290c318244a7", tags: editFormData?.tags || [], categoryId: editFormData?.categoryId || "", }; const [doFetchTags] = useThunk(fetchTags); const [doFetchCategories] = useThunk(fetchCategories); const { data: categoryData } = useAppSelector((state) => state.category); const { data: tagData } = useAppSelector((state) => state.tags); const { control, handleSubmit, formState: { errors }, reset, } = useForm<formPostValidationType>({ resolver: yupResolver(schema), defaultValues: initialFormValues, }); // 仅保留手动管理的image状态(用于文件上传) const [image, setImage] = useState(initialFormValues.image); const onSubmit = function (data: any) { const formData = new FormData(); formData.append("title", data.title); formData.append("body", data.body); formData.append("image", image); formData.append("userId", data.userId); formData.append("categoryId", data.categoryId); formData.append("isPublished", data.isPublished); formData.append("publishedAt", ""); // 从RHF的data中获取tags值 data.tags.forEach(tagId => formData.append("tags[]", tagId)); typeOperation === "Add" ? onAdd(formData) : onEdit(formData); // 同步重置RHF状态和自定义image状态 reset(initialFormValues); setImage(initialFormValues.image); }; useEffect(() => { doFetchTags({ all: true }); doFetchCategories({ all: true }); }, [doFetchTags, doFetchCategories]); return ( <> <Grid container sx={addEditFormStyle}> <form style={{ width: "100%", flexWrap: "wrap" }} onSubmit={handleSubmit(onSubmit)} > <Grid container mb={3} spacing={2}> <Grid item xl={6}> <Controller name="tags" control={control} render={({ field }) => ( <Autocomplete id="tags" multiple options={tagData} getOptionLabel={(option: any) => option?.title || ""} fullWidth sx={{ marginRight: "10px" }} // 直接从RHF的field.value匹配选中项 value={tagData.filter((option: tagsData) => { return field.value.includes(option.id); })} onChange={(event, newValue) => { // 仅更新RHF的表单状态 const value = newValue.map((option: tagsData) => option.id); field.onChange(value); }} renderInput={(params) => ( <TextField error={errors.tags ? true : false} {...params} label="تگ ها" helperText={errors.tags && errors.tags.message} /> )} /> )} /> </Grid> </Grid> {/* 其他表单组件需同步调整为使用RHF的Controller/register,确保状态统一 */} </form> </Grid> </> ); };
关键修改点说明
- 移除冗余的自定义
form状态,仅保留image处理文件上传逻辑 - Autocomplete的
value改为从RHF的field.value匹配,不再依赖外部状态 - 提交时直接使用RHF返回的
data.tags,避免多状态源取值不一致 - 重置时同步更新RHF状态和自定义
image状态,确保所有表单元素清空
内容的提问来源于stack exchange,提问作者Behnam
相关产品推荐
相关产品推荐

