React自定义TextField组件清除按钮功能失效问题求助
自定义React TextField清除按钮失效问题修复
我编写了一个带清除按钮的自定义React TextField组件,搭配react-hook-form的Controller使用,但清除按钮点击后无法正常清空输入框内容,相关代码如下:
表单初始化代码
const { handleSubmit, control, formState } = useForm<SignInModel>({ resolver: zodResolver(signinSchema), defaultValues: signinDefaultValue, });
Controller调用代码
<Controller name="email" control={control} render={({ field: { ref, ...field } }) => ( <ValidationTextField label={t("auth.email")} type="email" autoComplete="email" helperText={!!errors.email && (isDirty || isSubmitted) ? String(errors.email.message) : null} {...field} /> )} />
自定义ValidationTextField组件实现
interface ValidationTextFieldProps extends Omit<FilledTextFieldProps, "variant"> {} export function ValidationTextField(props: ValidationTextFieldProps) { const [value, setValue] = useState(""); return ( <TextField required margin="normal" fullWidth helperText={props.helperText} error={!!props.helperText} onChange={(e) => setValue(e.target.value)} value={value} FormHelperTextProps={{ style: { width: "fit-content", marginRight: 0 }, }} InputProps={{ endAdornment: !!props.value && ( <IconButton aria-label="toggle password visibility" onClick={() =>{ setValue("") }} > <CancelRoundedIcon /> </IconButton> ), }} {...props} /> ); }
问题原因分析
- 状态冲突:组件内部维护了独立的
value状态,但最后通过{...props}覆盖了onChange和value属性,导致内部状态完全失效,实际使用的是props传递的表单字段值。 - 清除逻辑不同步:点击清除按钮时仅更新了内部state,未触发props中的
onChange回调,导致react-hook-form的表单状态未更新,输入框内容无法真正清空。 - 显示判断不一致:清除按钮的显示条件依赖
props.value,但内部state与props.value不同步,可能出现按钮显示异常。
修复后的组件代码
interface ValidationTextFieldProps extends Omit<FilledTextFieldProps, "variant"> {} export function ValidationTextField(props: ValidationTextFieldProps) { // 移除内部状态,直接复用props传递的表单字段状态 const handleClear = () => { // 调用props的onChange回调,同步更新表单状态 props.onChange?.({ target: { value: "" } } as React.ChangeEvent<HTMLInputElement>); }; return ( <TextField required margin="normal" fullWidth helperText={props.helperText} error={!!props.helperText} FormHelperTextProps={{ style: { width: "fit-content", marginRight: 0 }, }} InputProps={{ endAdornment: !!props.value && ( <IconButton aria-label="清除输入内容" onClick={handleClear} > <CancelRoundedIcon /> </IconButton> ), }} {...props} // 保留props在最后,确保表单字段的value和onChange生效 /> ); }
修复说明
- 移除组件内部的
useState,直接依赖react-hook-form通过field传递的value和onChange,保证输入框状态与表单完全同步。 - 清除按钮点击时调用
props.onChange清空值,触发表单状态更新,输入框内容会随之清空。 - 调整按钮的
aria-label为更准确的“清除输入内容”,提升组件可访问性。
内容的提问来源于stack exchange,提问作者durmus yasar
相关产品推荐
相关产品推荐

