记 antd 的表单校验部分失效的问题

132 阅读1分钟

背景

我有一个表单,其中部分的字段需要根据后端配置的正则表达式来校验合法性。我按照下面的写法,可以在修改字段时触发正则校验。

function App() {
  const [configs, setConfigs] = useState(null)

  useEffect(() => {
    getConfigs().then((c) => setConfigs(c))
  }, [])
  
  const onSubmit = (values) => {}

  return (
    <Form onFinish={onSubmit}>
      <Form.Item label="First Name" name="firstName" rules={[{ pattern: configs?.nameReg, message: 'Invalid input' }]}>
        <Input />
      </Form.Item>
      <Form.Item>
        <Button htmlType="submit">Submit</Button>
      </Form.Item>
    </Form>
  )
}

但是,我可能会使用 form.setFieldsValue 来修改表单项,其中可能会传入非法值,这时候并不会触发自动校验,所以只能等待提交的时候自动触发。然而,表单的校验并没有使正则表达式的限制生效。

问题定位

猜测 rules 参数在表单构建的时候就初始化了,可能不会监听依赖项更新,于是我将 rules 中的 pattern 修改为常量正则表达式,发现正则的限制生效了。

解决方案

使用 useRef 来保存配置项,以便能获取到最新的正则表达式。

function App() {
  const configs = useRef(null)

  useEffect(() => {
    getConfigs().then((c) => configs.current = c)
  }, [])
  
  const onSubmit = (values) => {}

  return (
    <Form onFinish={onSubmit}>
      <Form.Item label="First Name" name="firstName" rules={[{ pattern: configs.current?.nameReg, message: 'Invalid input' }]}>
        <Input />
      </Form.Item>
      <Form.Item>
        <Button htmlType="submit">Submit</Button>
      </Form.Item>
    </Form>
  )
}