Antd Form中动态设置Form.Item的值无效?

Antd Form 设置动态Item的值无效
image.png

在代码中我动态生成了Form.Item,在Item内设置initialValue无效。
就换了一种方式,使用form.setFieldsValue去设置表单值,在点击确定时,表单有值,也通过了校验, 但就是不显示值,请问是什么原因呢?

const RenderForm = () => {


  const [form] = Form.useForm();
  useEffect(() => {
    if (deviceType) {
      let map = {};
      deviceType.customers.forEach((item) => {
        map[item.id] = JSON.parse(item.defaultValue);
      });
      console.log('设置表单', map);
      form.setFieldsValue({ customers: map });
      setTimeout(() => {
        let values = form.getFieldsValue();
        console.log('values是', values);
      }, 1000);
    }
  }, [deviceType]);

  const getFormItems = () => {
    console.log('deviceType', deviceType);
    if (deviceType?.customers && deviceType.customers.length > 0) {
      return deviceType.customers.map((item) => (
        <Form.Item
          key={item.id}
          label={item.name}
          name={['customers', item.id]}
          rules={JSON.parse(item.rules)}
        >
          {getComponent(item.dataType, JSON.parse(item.dataConfig))}
        </Form.Item>
      ));
    }
    return null;
  };
return (
    <Form form={form} onFinish={onFinish}>
      <Form.Item label="名称" name="name" rules={getRules(RuleType.notOnlySpace, true, 30)}>
        <Input />
      </Form.Item>
      {getFormItems()}
      <Row justify="end">
        <Space align="end">
          <Button onClick={handleCancel}>取消</Button>
          <Button type="primary" htmlType="submit">确定</Button>
        </Space>
      </Row>
    </Form>
  );
}

getComponent 这个方法里把 Select 和InputNumber封装了一下,所以无法显示值,该怎么避免这个问题呢

阅读 2.2k
avatarAI BotBETA

您遇到的问题可能是由于Ant Design的表单组件在渲染时有一定的异步性。当您使用form.setFieldsValue动态设置表单字段的值时,这些值可能不会立即反映在表单上。

在您的代码中,您尝试在设置字段值后立即获取这些值,这可能会因为表单尚未完成更新而导致获取的值不正确。

为了解决这个问题,您可以尝试使用form.validateFields方法代替form.getFieldsValueform.validateFields不仅可以获取表单字段的值,还可以确保表单字段已经被正确地更新和验证。此外,form.validateFields还可以接收一个回调函数,该函数会在所有字段都通过验证后执行,此时您就可以获取到最新的字段值了。

以下是修改后的代码示例:

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

  useEffect(() => {
    if (deviceType) {
      let map = {};
      deviceType.customers.forEach((item) => {
        map[item.id] = JSON.parse(item.defaultValue);
      });
      console.log('设置表单', map);
      form.setFieldsValue({ customers: map });
    }
  }, [deviceType]);

  const getFormItems = () => {
    if (deviceType?.customers && deviceType.customers.length > 0) {
      return deviceType.customers.map((item) => (
        <Form.Item
          key={item.id}
          label={item.name}
          name={['customers', item.id]}
          rules={JSON.parse(item.rules)}
        >
          {getComponent(item.dataType, JSON.parse(item.dataConfig))}
        </Form.Item>
      ));
    }
    return null;
  };

  const onFinish = (values) => {
    console.log('表单值', values);
    // 在这里处理表单提交逻辑
  };

  return (
    <Form form={form} onFinish={onFinish}>
      <Form.Item label="名称" name="name" rules={[{ required: true, message: '请输入名称', whitespace: true }]}>
        <Input />
      </Form.Item>
      {getFormItems()}
      <Row justify="end">
        <Space align="end">
          <Button onClick={() => form.resetFields()}>取消</Button>
          <Button type="primary" htmlType="submit">确定</Button>
        </Space>
      </Row>
    </Form>
  );
};

在这个示例中,我去掉了handleCancel函数,因为您没有提供具体的实现,我将其替换为了form.resetFields()方法,该方法用于重置表单字段的值。此外,我也修改了Form.Item中的rules属性,将其替换为了一个数组,这是Ant Design表单组件要求的规则格式。

请注意,form.validateFields方法默认会触发表单的验证,如果表单中有字段未通过验证,该方法会返回一个包含错误信息的对象。如果您想要忽略验证并直接获取字段值,您可以将form.validateFields的第二个参数设置为{ force: true }

希望这个答案能够解决您的问题!如果您还有其他问题或需要进一步的帮助,请随时向我提问。

1 个回答

虽然不知道原因,但是我把Component封装过的 Select 和Input 添加了一个defaultValue,设置为初始值,就可以了

<Select
      width="100%"
      options={options}
      defaultValue={props.defaultValue}
    />
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进