比赛晋级
https://www.photophoto.cn/tupian/bisaijinjibiao.html

https://blog.csdn.net/m0_58293192/article/details/130752396
https://blog.csdn.net/GongWei_/article/details/119675911
https://www.lodashjs.com/docs/lodash.mergeWith#_mergewithobject-sources-customizer
https://segmentfault.com/a/1190000021187809

React Context说到底只是组件
当Context.Provider重新渲染的时候,它所有的子组件都被重新渲染了
for of 支持 return和 break,
缺点:没有 index
for of获取 index,用 entries(),
entries()返回一个可迭代的对象,包含数组的键值对 [key, value];迭代对象中的数组索引作为 key,数组元素作为 value
for in需要判断 hasOwnProperty

  1. for (const item of arr) {}
  2. for (const [index, item] of arr.entries()) {}
  3. function showMessage(success) {
  4. message.destroy();
  5. message.success('禁用成功');
  6. }
  7. function propsEqual(oldProps, props) {
  8. return isEqual(oldProps, props);
  9. }
  10. const values = {
  11. user: {
  12. name: '',
  13. phone: [135, 136, 136]
  14. }
  15. }
  16. <Form.List name="user">
  17. {(fields, { add, remove }) => (
  18. <>
  19. <Item>
  20. <Button type="dashed" onClick={() => add({
  21. name: '',
  22. phone: [{begin: '', end: ''}],
  23. })} icon={<PlusOutlined/>}>
  24. 新增用户
  25. </Button>
  26. </Item>
  27. {fields.map((field) => (
  28. <div className="flex">
  29. <Row gutter={16} key={field.key} className="flex-1">
  30. <Col span={24}>
  31. <Item
  32. {...field}
  33. name={[field.name, 'name']}
  34. rules={[{ required: true, message: '请输入用户名' }]}
  35. >
  36. <Input />
  37. </Item>
  38. </Col>
  39. <Col span={24}>
  40. <Phone name={[field.name, 'phone']} />
  41. </Col>
  42. </Row>
  43. <Button
  44. type="link"
  45. onClick={() => remove(field.name)}
  46. >
  47. <MinusCircleOutlined />
  48. </Button>
  49. </div>
  50. ))}
  51. </>
  52. )}
  53. </Form.List>
  54. //
  55. <Form.List name="level1List">
  56. {(level1Fields) => (
  57. <div>
  58. {level1Fields.map((level1Field, level1Index) => (
  59. <Form.List name={[level1Field.name, 'level2List']} // notice here, using name path
  60. {(level2Fields) => (
  61. <div>
  62. {level2Fields.map((level2Field, level2Index) => (
  63. <Form.Item
  64. name={[level2Field.name, 'key']} // notice the field name should be level2Field.name
  65. >
  66. <Input />
  67. </Form.Item>
  68. )}
  69. </div>
  70. )}
  71. </Form.List>
  72. )}
  73. </div>
  74. )}
  75. </Form.List>

https://github.com/ant-design/ant-design/issues/23065
https://blog.csdn.net/zxz_learn/article/details/119896800

Phone 子节点

  1. import React, { Fragment } from 'react';
  2. import { array } from 'prop-types';
  3. import { Form, Input, Row, Col, Button } from 'antd4';
  4. import { PlusCircleOutlined, MinusCircleOutlined } from '@ant-design/icons';
  5. const { Item } = Form;
  6. Phone.propTypes = {
  7. name: array.isRequired,
  8. };
  9. function Phone(props){
  10. const { name } = props;
  11. return (
  12. <Form.List name={name}>
  13. {(fields, { add, remove }) => (
  14. <Fragment>
  15. {fields.map((field) => (
  16. <div className="flex">
  17. <Row gutter={16} key={field.key} className="flex-1">
  18. <Col span={12}>
  19. <Item
  20. {...field}
  21. name={[field.name, 'begin']}
  22. rules={[{ required: true, message: '请输入开始时间' }]}
  23. >
  24. <Input
  25. placeholder="请输入开始时间"
  26. />
  27. </Item>
  28. </Col>
  29. <Col span={12}>
  30. <Item
  31. {...field}
  32. name={[field.name, 'end']}
  33. rules={[{ required: true, message: '请输入结束时间' }]}
  34. >
  35. <Input
  36. placeholder="请输入结束时间"
  37. />
  38. </Item>
  39. </Col>
  40. </Row>
  41. <div>
  42. <Button
  43. type="link"
  44. onClick={() => remove(field.name)}
  45. >
  46. <MinusCircleOutlined/>
  47. </Button>
  48. <Button
  49. type="link"
  50. onClick={() => add({ begin: '', end: '' })}
  51. >
  52. <PlusCircleOutlined/>
  53. </Button>
  54. </div>
  55. </div>
  56. ))}
  57. </Fragment>
  58. )}
  59. </Form.List>
  60. );
  61. }
  62. export default Phone;