【问题标题】:React Ant Design form.resetFields() doesn't call onChange event of <Form.Items>React Ant Design form.resetFields() 不调用 <Form.Items> 的 onChange 事件
【发布时间】:2021-12-01 16:17:09
【问题描述】:

我有一个带有 &lt;Form.Items&gt; 的 Ant Design &lt;Form&gt; 组件,它有 onChange 事件。如果 onChange 事件函数为真,我将显示额外的内容。 因此,在我创建的示例沙箱中,当将所有 &lt;Radio&gt; 更改为 Yes 时,它会触发经过验证的 onChange 事件,然后显示一个带有文本“你检查了所有答案为是”的 div。 由于我使用的是&lt;Form&gt;,它是一个表单控制的环境,所以我使用form 来设置和重置值。但是当调用form.resetFields() 时,不会调用 onChange 处理程序。所以消息不会因为状态不刷新而消失。所以我必须找到一种方法来从父组件中调用一个函数来刷新子组件中的表单值。 对每个字段使用useImperativeHandle() 来更新更复杂的表单以从父级调用函数对于这样一个简单的任务来说似乎太复杂了。在阅读此stack overflow thread 时,添加自定义事件以与父组件进行通信似乎不是一种反应灵敏的方式 我缺少 Ant Design 表单中的某些内容吗?因为这一定是一项共同的任务。解决这个问题的好方法是什么?

通过示例链接到代码沙箱:

https://codesandbox.io/s/vigilant-curran-dqvlc?file=/src/AntDFormChild.js

示例

const formLayout = {
  labelCol: { span: 8 },
  wrapperCol: { span: 7 }
};

const questionDefaultValues = {
  rjr01_q01: 2,
  rjr02_q01: 2
};

const AntDForm = () => {
  const [form] = Form.useForm();

  const handleResetForm = () => {
    form.resetFields();
    // now force onChange of child component to update
  };

  const handleFillForm = () => {
    form.setFieldsValue({ rjr01_q01: 1, rjr02_q01: 1 });
    // now force onChange of child component to update
  };

  return (
    <>
      <Button onClick={handleResetForm}>Reset Form</Button>
      <Button onClick={handleFillForm}>Fill Form</Button>
      <Form
        {...formLayout}
        form={form}
        initialValues={{ ...questionDefaultValues }}
      >
        <AntDFormChild form={form} />
      </Form>
    </>
  );
};

const questionQualifiedValues = {
  rjr01_q01: 1,
  rjr02_q01: 1
};

const AntDFormChild = ({ form }) => {
  const [isQualified, setIsQualified] = useState(false);
  const [questionFormValues, setQuestionFormValues] = useState({});

  useEffect(() => {
    if (shallowEqual(questionFormValues, questionQualifiedValues)) {
      setIsQualified(true);
    } else {
      setIsQualified(false);
    }
  }, [questionFormValues]);

  function shallowEqual(object1, object2) {
    const keys1 = Object.keys(object1);
    const keys2 = Object.keys(object2);
    if (keys1.length !== keys2.length) {
      return false;
    }
    for (let key of keys1) {
      if (object1[key] !== object2[key]) {
        return false;
      }
    }
    return true;
  }

  return (
    <>
      {isQualified && (
        <div style={{ color: "red" }}>You checked all answered with yes</div>
      )}
      <Form.Item name="rjr01_q01" label="Question 1">
        <Radio.Group
          onChange={(i) => {
            setQuestionFormValues((questionFormValues) => ({
              ...questionFormValues,
              rjr01_q01: i.target.value
            }));
          }}
        >
          <Radio value={1}>Yes</Radio>
          <Radio value={0}>No</Radio>
          <Radio value={2}>Unknown</Radio>
        </Radio.Group>
      </Form.Item>
      <Form.Item name="rjr02_q01" label="Question 2">
        <Radio.Group
          onChange={(i) => {
            setQuestionFormValues((questionFormValues) => ({
              ...questionFormValues,
              rjr02_q01: i.target.value
            }));
          }}
        >
          <Radio value={1}>Yes</Radio>
          <Radio value={0}>No</Radio>
          <Radio value={2}>Unknown</Radio>
        </Radio.Group>
      </Form.Item>
    </>
  );
};

【问题讨论】:

    标签: javascript reactjs antd


    【解决方案1】:

    由于AntD Form不受控制,所以无法通过调用resetFields、setFieldsValues来触发onChange事件。 我认为您的目标是根据表单值显示消息,最好的方法是使用Form.Item,它可以访问表单状态。

    https://codesandbox.io/s/antd-form-item-based-on-other-item-ens59?file=/src/AntDFormChild.js

    【讨论】:

    • 你是英雄!谢谢。为什么我没有在 shouldUpdate 中进一步调查的两个有趣事实,一个是 &lt;Form.Item&gt;only 调用 shouldUpdate 如果 ({getFieldValue}) 包含在 &lt;Form.Item&gt; 子项中,其次,这对我来说是最令人困惑的部分,当记录 shouldUpdates{(prevValues, currentValues)重置表单时prevValues和currentValues是相同的。这就是为什么我认为它行不通。
    • 你知道为什么它们是一样的,它仍然有效吗?
    猜你喜欢
    • 1970-01-01
    • 2019-10-22
    • 2019-01-22
    • 2021-01-22
    • 1970-01-01
    • 2020-03-22
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多