【问题标题】:How to render an element when form.isFieldsTouched() changesform.isFieldsTouched() 改变时如何渲染元素
【发布时间】:2021-05-07 10:39:23
【问题描述】:

我正在将 ant-design 迁移到 v4,我不确定迁移以下案例的推荐方法是什么。

我有一个带有输入和提交按钮的表单。除非form.isFieldsTouched() === true,否则不会呈现提交按钮。在 v3 中,这不是实现的问题。 Antd v4 使用了 hooks,这成了一个问题。

考虑以下形式。输入更改后,提交按钮将不会呈现。 https://codesandbox.io/s/zealous-rgb-pc7ke?file=/src/App.js

import { Form, Input } from "antd";

export default function App() {
  const [form] = Form.useForm();
  return (
    <Form form={form}>
      <Form.Item name="name">
        <Input />
      </Form.Item>
      {form.isFieldsTouched() && <button type="submit">Submit</button>}
    </Form>
  );
}

有一种“方法”可以让它工作和渲染,但感觉是错误的和 hacky。 Form.Item 还添加了不需要的样式。 https://codesandbox.io/s/delicate-browser-0y9f9?file=/src/App.js

import { useState } from 'react';
import { Form, Input } from "antd";

export default function App() {
  const [form] = Form.useForm();
  const [isTouched, setIsTouched] = useState(form.isFieldsTouched());
  return (
    <Form form={form}>
      <Form.Item name="name">
        <Input />
      </Form.Item>
      <Form.Item 
        shouldUpdate={() => {
          const didChange = form.isFieldsTouched() !== isTouched;
          if (didChange) {
            setIsTouched(form.isFieldsTouched());
          }
          return didChange;
        }}
      >
        {() => form.isFieldsTouched() && <button type="submit">Submit</button>}
      </Form.Item>
    </Form>
  );
}

你有类似的案例吗?你是怎么解决的?

【问题讨论】:

  • antd 在后台使用rc-field-form,而您需要使用这些黑客的原因是该库的 API 设计不佳。它应该通过摆脱无处不在的渲染来提高渲染性能,但不提供 API 来订阅表单状态的某些更改。对我来说,这是过早的优化,因为大多数表单不需要那种程度的渲染性能。它弊大于利。只是我的观点。我喜欢使用formik,它允许您在确实需要优化时选择加入。
  • @trixn 感谢您的解释。现在我意识到像form.getFieldValue('some-field') 这样的其他方法也会有类似的问题,并且使用像上面这样的黑客来解决它会很快变得非常复杂。这个DX很差,我会考虑迁移到另一个表单库。
  • 这是与您的问题相关的问题:github.com/react-component/field-form/issues/153。表单渲染是 React 中较难的事情之一。我知道 3 个流行的 react 表单库:formik、react-final-form 和 react-hook-form,它们都有自己的怪癖。老实说,我不知道他们与 antd 组件一起工作的效果如何。使用rc-field-form 可能会有更优雅的解决方案,但据我所知,通过阅读文档,没有明显的方法可以更好地处理您的具体问题。

标签: javascript reactjs react-hooks antd


【解决方案1】:

我遇到了类似的问题,当时我是这样解决的:

import { useState } from "react";
import { Form, Input } from "antd";

export default function App() {
  const [form] = Form.useForm();
  const [isTouched, setIsTouched] = useState();

  return (
    <Form
      form={form}
      onFieldsChange={() => {
        // add your additionaly logic here
        setIsTouched(true);
      }}
    >
      <Form.Item name="name">
        <Input />
      </Form.Item>
      <Form.Item>
        {isTouched && <button type="submit">Submit</button>}
      </Form.Item>
    </Form>
  );
}

【讨论】:

    【解决方案2】:

    我也有类似的问题。这对我有用。

    import { useState } from 'react';
    import { Form, Input } from "antd";
    
    export default function App() {
      const [form] = Form.useForm();
      return (
        <Form form={form}>
          <Form.Item name="name">
            <Input />
          </Form.Item>
          <Form.Item 
            shouldUpdate={true}
          >
            {() => form.isFieldsTouched() && <button type="submit">Submit</button>}
          </Form.Item>
        </Form>
      );
    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 2021-07-18
      • 2022-11-01
      • 2018-01-09
      • 2021-11-20
      • 1970-01-01
      相关资源
      最近更新 更多