You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React+Material UI中使用react-imask实现输入掩码,点击提交后手机号内容清空问题求助

解决Material UI + React Hook Form + Input Mask提交后输入框清空的问题

我帮你排查了代码里的几个关键问题,这应该就是导致提交后手机号输入框内容清空的原因:


问题1:输入框name属性不匹配

你的Input组件设置的name="cpf",但表单校验的字段是phoneNumber,这会导致React Hook Form无法正确关联输入值,提交时无法识别这个字段,进而引发状态同步异常。

问题2:handleSubmit的使用方式错误

你直接给按钮的onClick绑定了handleSubmit(onSubmit),正确的做法应该是把handleSubmit(onSubmit)绑定到form标签的onSubmit事件上,按钮只需要设置type="submit"即可。直接用onClick会绕过表单的默认提交逻辑,可能触发不必要的状态重置。

问题3:自定义掩码组件与React Hook Form的整合问题

对于自定义输入组件(比如带掩码的IMaskInput),React Hook Form推荐使用Controller组件来包裹,而不是直接传递register,这样能更可靠地同步表单状态和输入值,避免因自定义onChange导致的状态不同步。


修正后的完整代码

import { forwardRef } from 'react';
import { IMaskInput } from 'react-imask';
import { Input, Button, FormControl, FormHelperText } from '@mui/material';
import { useForm, Controller } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as Yup from 'yup';

const TextMaskCustom = forwardRef((props, ref) => {
  const { onChange, ...rest } = props;
  // 调整onAccept逻辑,确保传递正确的值给React Hook Form
  return (
    <IMaskInput
      mask="000-000-0000"
      definitions={{ "#": /[1-9]/ }}
      inputRef={ref}
      onAccept={(value) => onChange(value)}
      overwrite
      {...rest}
    />
  );
});

export default function App() {
  const schema = Yup.object().shape({
    phoneNumber: Yup.string().required("Required!")
  });

  const { control, formState: { errors }, handleSubmit } = useForm({
    resolver: yupResolver(schema)
  });

  const onSubmit = (data) => {
    console.log('提交的手机号:', data.phoneNumber);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} style={{ padding: 20 }}>
      <FormControl error={!!errors.phoneNumber} fullWidth margin="normal">
        <Controller
          name="phoneNumber"
          control={control}
          defaultValue=""
          render={({ field }) => (
            <Input
              {...field}
              inputComponent={TextMaskCustom}
              placeholder="请输入手机号(格式:000-000-0000)"
            />
          )}
        />
        {errors.phoneNumber && (
          <FormHelperText>{errors.phoneNumber.message}</FormHelperText>
        )}
      </FormControl>
      <Button type="submit" variant="contained" color="primary">
        提交
      </Button>
    </form>
  );
}

关键改动说明

  1. 统一字段name:把Input关联的字段名改为phoneNumber,和表单校验字段保持一致,确保React Hook Form能正确追踪值变化。
  2. 使用Controller包裹自定义输入:通过Controller组件接管自定义掩码输入的状态管理,它会自动同步valueonChange逻辑,避免手动处理的状态不同步问题。
  3. 修正表单提交逻辑:将handleSubmit(onSubmit)绑定到form的onSubmit事件,按钮设置为type="submit",遵循标准表单提交流程,避免异常重置。
  4. 简化掩码组件的回调逻辑:直接将掩码处理后的值传递给Controller的onChange,确保表单能正确获取到格式化后的输入值。

这样修改后,提交表单时输入框的内容就不会被清空,同时表单验证和值同步也能正常工作了。

内容的提问来源于stack exchange,提问作者Wang Ming

火山引擎 最新活动