关于antd form中List使用setFieldValue的踩坑记录

489 阅读1分钟

先上示例代码

import React, { useEffect } from 'react';
import './index.css';
import { CloseOutlined } from '@ant-design/icons';
import { Button, Card, Form, Input, Space, Typography } from 'antd';

const App: React.FC = () => {
  const [form] = Form.useForm();
  useEffect(() => {
    setTimeout(() => {
      form.setFieldValue(['list', 0], {second: 2});
    }, 1000);
  }, [form]);
  
  return (
    <Form
      labelCol={{ span: 6 }}
      wrapperCol={{ span: 18 }}
      form={form}
      name="dynamic_form_complex"
      style={{ maxWidth: 600 }}
      // autoComplete="off"
      initialValues={{ list: [null] }}
    >
      <Form.List name={['list']}>
        {(subFields, subOpt) => (
          <div style={{ display: 'flex', flexDirection: 'column', rowGap: 16 }}>
            {subFields.map((subField) => (
              <Space key={subField.key}>
                <Form.Item name={[subField.name, 'first']}>
                  <Input placeholder="first" />
                </Form.Item>
                <Form.Item name={[subField.name, 'second']}>
                  <Input placeholder="second" />
                </Form.Item>
              </Space>
            ))}
          </div>
        )}
      </Form.List>

      <Form.Item noStyle shouldUpdate>
        {() => (
          <Typography>
            <pre>{JSON.stringify(form.getFieldsValue(), null, 2)}</pre>
          </Typography>
        )}
      </Form.Item>
    </Form>
  );
};

export default App;

该例子渲染了一个Form表单,其中list字段为一个数组,对应的是List组件,初始化时,其中有一个元素为null(该操作是为了可以渲染出组件)

在组件初次挂载后,会设置一个定时器,在一秒后通过setFieldValue更新对应数组的下标为0的元素

然后下方会有一片区域展示getFieldsValue的值

初始内容如下:

image.png

image.png

一秒后的样式如下:

image.png

此时通过setFieldValue触发了组件的正常渲染

这个时候更改setFieldValue中的namePath参数(第一个参数)

form.setFieldValue(['list', '0'], {second: 2});

等待一秒后,情况如下:

image.png

总结

当下标使用string而不是number时,可以成功更新表单内部的值,但是不会触发注册的组件自动渲染