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


1、noStyle shouldUpdate

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

2、Form List

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

3、Item children

ItemChildren.png

  1. import React, { FC, useEffect } from 'react';
  2. import { Form, Switch, Input, Button } from 'antd';
  3. import { MinusCircleOutlined } from '@ant-design/icons'
  4. import FormItemChildrenTest from './components/formItemChildrenTest';
  5. const { Item, List, useForm } = Form;
  6. /** Form管理测试组件 */
  7. const Test: FC = props => {
  8. const [form] = useForm();
  9. useEffect(() => {
  10. form.setFields([{ name: 'children', value: { a: '1', b: '2' } }])
  11. }, []);
  12. return (
  13. <Form form={form} onValuesChange={values => console.log(values)}>
  14. {/* noStyle shouldUpdate用法 */}
  15. <Item noStyle shouldUpdate={(prev, current) => prev.switch !== current.switch}>
  16. {({ getFieldValue }) => {
  17. const testSwitch = getFieldValue('switch');
  18. return <>
  19. <Item name='switch' valuePropName='checked'>
  20. <Switch />
  21. </Item>
  22. {
  23. testSwitch && <Item name='content'>
  24. <div>noStyle shouldUpdate 用法</div>
  25. </Item>
  26. }
  27. </>
  28. }}
  29. </Item>
  30. {/* children的用法 */}
  31. <Item name='children'>
  32. <FormItemChildrenTest />
  33. </Item>
  34. </Form>
  35. );
  36. };
  37. export default Test;
  1. import React, { FC } from 'react';
  2. import { Form, Switch } from 'antd';
  3. import $ from './style.less';
  4. interface Props {
  5. /** Item为children添加的 */
  6. value?: string;
  7. /** Item为children添加的 */
  8. onChange?: (value: any) => void;
  9. }
  10. /** FormItem子组件测试*/
  11. const ItemChildrenTest: FC<Props> = props => {
  12. /**
  13. * @desc value初始值可以直接通过父组件form.setFieldsValue()设置
  14. * ItemChildrenTest的状态可以通过Item为children添加的onChange事件传递给父组件
  15. * 在父组件中通过onValuesChange直接获取到
  16. */
  17. const { value, onChange } = props;
  18. return (
  19. <div onClick={() => typeof onChange === 'function' && onChange('可以直接在父组件中拿到')}>
  20. 测试
  21. </div>
  22. );
  23. };
  24. export default ItemChildrenTest;
  1. import React, { FC, useEffect } from 'react';
  2. import { Form, Switch, Input, Button } from 'antd';
  3. import { MinusCircleOutlined } from '@ant-design/icons'
  4. import FormItemChildrenTest from './components/formItemChildrenTest';
  5. const { Item, List, useForm } = Form;
  6. /** Form管理测试组件 */
  7. const Test: FC = props => {
  8. const [form] = useForm();
  9. useEffect(() => {
  10. form.setFields([{ name: 'children', value: { a: '1', b: '2' } }])
  11. }, []);
  12. return (
  13. <Form form={form} onValuesChange={values => console.log(values)}>
  14. <List name='list'>
  15. {(fields, { add, remove }, { errors }) => (
  16. <>
  17. {fields.map((field, index) => {
  18. // console.log(fields)
  19. // console.log(add)
  20. // console.log(field)
  21. return <Item
  22. label={`添加的第${index + 1}行`}
  23. required={false}
  24. key={field.key}
  25. >
  26. <Item
  27. {...field}
  28. validateTrigger={['onChange', 'onBlur']}
  29. noStyle
  30. >
  31. <Input />
  32. </Item>
  33. {fields.length > 1
  34. ? <MinusCircleOutlined onClick={() => remove(field.name)} />
  35. : null}
  36. </Item>
  37. })}
  38. <Item>
  39. <Button onClick={() => add()}>
  40. 添加一行
  41. </Button>
  42. <Button onClick={() => add('defaultValue', 0)}>
  43. 在顶部添加一行
  44. </Button>
  45. <Form.ErrorList errors={errors} />
  46. </Item>
  47. </>
  48. )}
  49. </List>
  50. </Form>
  51. );
  52. };
  53. export default Test;