javascript - 如何使用 Antd InternalFormInstance 验证表单而不显示 UI 错误

标签 javascript reactjs forms validation antd

我正在尝试禁用表单提交按钮,直到验证完全通过。
我遇到了有关此主题的主题。
该线程有助于在不显示 UI 错误的情况下触发验证:
https://github.com/ant-design/ant-design/issues/25993
下面的代码在我的页脚按钮包装器的 hoc 中工作,但它正在验证所有要触摸的字段,甚至适用于非必填字段,这是不正确和预期的。

<Form.Item shouldUpdate>
    {() => (
      <Button
        type="primary"
        htmlType="submit"
        disabled={
          !!form
            .getFieldsError()
            .filter(({ errors }) => errors.length).length
        }
      >
        Log in
      </Button>
    )}
</Form.Item>
不幸的是,https://github.com/ant-design/ant-design/issues/23281线程全是中文,我看不懂。
我现有的form.validateFields是指formInstance,但它指的是:InternalFormInstance。
如何导入并验证? antd 4版本真的支持吗?
代码沙盒链接: https://codesandbox.io/s/gallant-merkle-21izz?file=/src/withFormWrapperHOC.tsx
作为引用的示例代码将很有帮助!
包含选择列表时,表单验证会严重失败。表单 onChange 或 onChangeValues 不起作用;当我们挖掘更多时,即使没有与 Select List 关联的验证规则,!form.isFieldsTouched(true) 也始终为 true。
引用票: https://github.com/ant-design/ant-design/issues/8436
看起来 Antd 在 Rc-select api 集成方面存在一些 Unresolved 问题,并且没有公开。
我们真的应该考虑 Antd 或任何其他表单验证吗?

最佳答案

要在第一次渲染时禁用验证,您可以使用 Ref 解决方法

const isMounting = React.useRef(false);
useEffect(() => {
  if (isMounting.current) {
    const disableStatus = !!form
      .getFieldsError()
      .filter(({ errors }) => errors.length).length;
    setIsDisabled(disableStatus);
  }
  else {
    isMounting.current = true
  }
}, [form]);

另一种选择是禁用登录按钮,直到填写所有表单输入,然后使用登录验证
import React, { useState } from "react";
import { Button, Form, Select } from "antd";
import "antd/dist/antd.css";

const { Option } = Select;

export function withFormWrapper(WrappedComponent: any) {
  return (props: any) => {
    const [form] = Form.useForm();
    const [isDisabled, setIsDisabled] = useState(true);

    function fieldIsEmpty(field) {
      let fieldValue = form.getFieldValue(field.name.join("."));
      return (
        fieldValue === undefined || [].concat(fieldValue).join().trim() === ""
      );
    }

    function fieldHasError(field) {
      return field.errors.length > 0;
    }

    function isValid() {
      const fields = form
        .getFieldsError()
        .filter((field) => fieldIsEmpty(field) || fieldHasError(field));

      console.log(fields);
      setIsDisabled(fields.length > 0);
    }

    const validate = () => {
      form
        .validateFields()
        .then((values: any) => {
          console.log("success");
        })
        .catch((errorInfo: any) => {
          console.log("failure");
        });
    };

    return (
      <Form form={form} onChange={isValid}>
        <WrappedComponent {...props} />
        <Form.Item name="gender" label="Gender" rules={[{ required: true }]}>
          <Select
            placeholder="Select a option and change input text above"
            onChange={isValid}
            allowClear
          >
            <Option value="male">male</Option>
            <Option value="female">female</Option>
            <Option value="other">other</Option>
          </Select>
        </Form.Item>
        <Form.Item>
          <Button
            type="default"
            htmlType="submit"
            onClick={() => form.resetFields()}
          >
            Cancel
          </Button>
        </Form.Item>

        <Form.Item shouldUpdate>
          {() => (
            <Button
              onClick={validate}
              type="primary"
              htmlType="submit"
              disabled={isDisabled}
            >
              Log in
            </Button>
          )}
        </Form.Item>
      </Form>
    );
  };
}
在这里工作example

Form.Provider onFormChange可以为选择组件触发验证
import React, { useState } from "react";
import { Button, Form, Select } from "antd";
import "antd/dist/antd.css";

const { Option } = Select;

export function withFormWrapper(WrappedComponent: any) {
  return (props: any) => {
    const [form] = Form.useForm();
    const [isDisabled, setIsDisabled] = useState(true);

    function fieldIsEmpty(field) {
      let fieldValue = form.getFieldValue(field.name.join("."));
      return (
        fieldValue === undefined || [].concat(fieldValue).join().trim() === ""
      );
    }

    function fieldHasError(field) {
      return field.errors.length > 0;
    }

    function isValid() {
      const fields = form
        .getFieldsError()
        .filter((field) => fieldIsEmpty(field) || fieldHasError(field));

      setIsDisabled(fields.length > 0);
    }

    const validate = () => {
      form
        .validateFields()
        .then((values: any) => {
          console.log("success");
        })
        .catch((errorInfo: any) => {
          console.log("failure");
        });
    };

    return (
      <Form.Provider onFormChange={isValid}>
        <Form form={form}>
          <WrappedComponent {...props} />
          <Form.Item
            name="gender"
            label="Gender"
            rules={[{ required: true }]}
            shouldUpdate
          >
            <Select
              placeholder="Select a option and change input text above"
              allowClear
            >
              <Option value="male">male</Option>
              <Option value="female">female</Option>
              <Option value="other">other</Option>
            </Select>
          </Form.Item>
          <Form.Item name="Tags" label="Tags" shouldUpdate>
            <Select
              mode="tags"
              style={{ width: "100%" }}
              placeholder="Tags Mode"
              onChange={handleChange}
            >
              {children}
            </Select>
          </Form.Item>
          <Form.Item>
            <Button
              type="default"
              htmlType="submit"
              onClick={() => form.resetFields()}
            >
              Cancel
            </Button>
          </Form.Item>

          <Form.Item shouldUpdate>
            {() => (
              <Button
                onClick={validate}
                type="primary"
                htmlType="submit"
                disabled={isDisabled}
              >
                Log in
              </Button>
            )}
          </Form.Item>
        </Form>
      </Form.Provider>
    );
  };
}
在这里工作example

关于javascript - 如何使用 Antd InternalFormInstance 验证表单而不显示 UI 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69379635/

相关文章:

javascript - ExpressJS 客户端 session 不保存 session

javascript - React 子组件未从父组件发送更新状态

javascript - 解构和克隆对象/一行?

javascript - 我的渲染方法做错了什么,导致我收到 "Invariant Violation"错误?

javascript - 尝试修复嵌套表单

javascript - 如何从模式 PHP Codeigniter 插入数据

html - 如果同一个表单上有多个提交按钮,如何使用 onsubmit() 来显示确认?

javascript - 向下滚动时在顶部浏览器中以固定模式制作 div

javascript - 设置 angularjs 对象数组绑定(bind)的选项

php - 从 Javascript 函数调用带有 MySQL 查询的 PHP 页面,然后将结果返回到另一个 javascript 函数