Antd v4 Form的使用

2,562 阅读1分钟

根据需求的不同,三种使用方式可以做到组件状态完全交给Form接管,会使组件看起来更加完整,可以减少冗余代码,其他人看你这部分代码的时候,不需要知道Form内部做了什么,只需要关心组件状态的变化,增加代码的可读性。


1、noStyle shouldUpdate

当组件中内部元素需要进行联动去控制状态,例如:通过开关去控制组件内其他元素的显示隐藏;这时候Form无法做到完全接管组件状态,必须通过Switch的onChange事件去控制,导致组件状态过多,代码冗余,组件完整度不够,这时候就可以使用noStyle、shouldUpdate的方式。

2、Form List

Form去管理一个数组的时候使用,例如:动态添加删除表单;

3、Item children

import React, { FC, useEffect } from 'react';
import { Form, Switch, Input, Button } from 'antd';
import { MinusCircleOutlined } from '@ant-design/icons'
import FormItemChildrenTest from './components/formItemChildrenTest';

const { Item, List, useForm } = Form;

/** Form管理测试组件 */
const Test: FC = props => {
  const [form] = useForm();
  useEffect(() => {
    form.setFields([{ name: 'children', value: { a: '1', b: '2' } }])
  }, []);
  return (
    <Form form={form} onValuesChange={values => console.log(values)}>
      {/* noStyle shouldUpdate用法 */}
      <Item noStyle shouldUpdate={(prev, current) => prev.switch !== current.switch}>
        {({ getFieldValue }) => {
          const testSwitch = getFieldValue('switch');
          return <>
            <Item name='switch' valuePropName='checked'>
              <Switch />
            </Item>
            {
              testSwitch && <Item name='content'>
                <div>noStyle shouldUpdate 用法</div>
              </Item>
            }
          </>
        }}
      </Item>
      {/* children的用法 */}
      <Item name='children'>
        <FormItemChildrenTest />
      </Item>
    </Form>
  );
};
export default Test;
import React, { FC } from 'react';
import { Form, Switch } from 'antd';
import $ from './style.less';

interface Props {
  /** Item为children添加的 */
  value?: string;
  /** Item为children添加的 */
  onChange?: (value: any) => void;
}
/** FormItem子组件测试*/
const ItemChildrenTest: FC<Props> = props => {
  /**
   * @desc value初始值可以直接通过父组件form.setFieldsValue()设置
   * ItemChildrenTest的状态可以通过Item为children添加的onChange事件传递给父组件
   * 在父组件中通过onValuesChange直接获取到
   */
  const { value, onChange } = props;
  return (
      <div onClick={() => typeof onChange === 'function' && onChange('可以直接在父组件中拿到')}>
        测试
      </div>
  );
};
export default ItemChildrenTest;
import React, { FC, useEffect } from 'react';
import { Form, Switch, Input, Button } from 'antd';
import { MinusCircleOutlined } from '@ant-design/icons'
import FormItemChildrenTest from './components/formItemChildrenTest';

const { Item, List, useForm } = Form;

/** Form管理测试组件 */
const Test: FC = props => {
  const [form] = useForm();
  useEffect(() => {
    form.setFields([{ name: 'children', value: { a: '1', b: '2' } }])
  }, []);
  return (
    <Form form={form} onValuesChange={values => console.log(values)}>
      <List name='list'>
        {(fields, { add, remove }, { errors }) => (
          <>
            {fields.map((field, index) => {
              // console.log(fields)
              // console.log(add)
              // console.log(field)
              return <Item
                label={`添加的第${index + 1}`}
                required={false}
                key={field.key}
              >
                <Item
                  {...field}
                  validateTrigger={['onChange', 'onBlur']}
                  noStyle
                >
                  <Input />
                </Item>
                {fields.length > 1
                  ? <MinusCircleOutlined onClick={() => remove(field.name)} />
                  : null}
              </Item>
            })}
            <Item>
              <Button onClick={() => add()}>
                添加一行
              </Button>
              <Button onClick={() => add('defaultValue', 0)}>
                在顶部添加一行
              </Button>
              <Form.ErrorList errors={errors} />
            </Item>
          </>
        )}
      </List>
    </Form>
  );
};
export default Test;