logoAnt Design

⌘ K
  • 디자인
  • 개발
  • 컴포넌트
  • 블로그
  • 자료
5.21.3
  • 为什么禁用日期这么难?
  • Why is it so hard to disable the date?
  • 封装 Form.Item 实现数组转对象
  • HOC Aggregate FieldItem
  • 行省略计算
  • Line Ellipsis Calculation
  • 📢 v4 维护周期截止
  • 📢 v4 surpassed maintenance period
  • Type Util
  • 一个构建的幽灵
  • A build ghost
  • 当 Ant Design 遇上 CSS 变量
  • Ant Design meets CSS Variables
  • API 기술 부채
  • 생동감 있는 Notification
  • 色彩模型与颜色选择器
  • Color Models and Color Picker
  • 主题拓展
  • Extends Theme
  • 虚拟表格来了!
  • Virtual Table is here!
  • Happy Work 테마
  • Happy Work Theme
  • 동적 스타일은 어디로 갔을까?
  • Suspense 引发的样式丢失问题
  • Suspense breaks styles
  • Bundle Size Optimization
  • 안녕, GitHub Actions
  • 所见即所得
  • To be what you see
  • 정적 메서드의 고통
  • SSR에서 정적 스타일 추출
  • SSR Static style export
  • 의존성 문제 해결
  • 贡献者开发维护指南
  • Contributor development maintenance guide
  • 转载-如何提交无法解答的问题
  • Repost: How to submit a riddle
  • 新的 Tooltip 对齐方式
  • Tooltip align update
  • Unnecessary Rerender
  • 如何成长为 Collaborator
  • How to Grow as a Collaborator
  • Funny Modal hook BUG
  • Modal hook 的有趣 BUG
  • about antd test library migration
  • antd 测试库迁移的那些事儿
  • Tree 的勾选传导
  • Tree's check conduction
  • getContainer 的一些变化
  • Some change on getContainer
  • Component-level CSS-in-JS

HOC Aggregate FieldItem

Resources

Ant Design Charts
Ant Design Pro
Ant Design Pro Components
Ant Design Mobile
Ant Design Mini
Ant Design Landing-Landing Templates
Scaffolds-Scaffold Market
Umi-React Application Framework
dumi-Component doc generator
qiankun-Micro-Frontends Framework
ahooks-React Hooks Library
Ant Motion-Motion Solution
China Mirror 🇨🇳

Community

Awesome Ant Design
Medium
Twitter
yuque logoAnt Design in YuQue
Ant Design in Zhihu
Experience Cloud Blog
seeconf logoSEE Conf-Experience Tech Conference
Work with Us

Help

GitHub
Change Log
FAQ
Bug Report
Issues
Discussions
StackOverflow
SegmentFault

Ant XTech logoMore Products

yuque logoYuQue-Document Collaboration Platform
AntV logoAntV-Data Visualization
Egg logoEgg-Enterprise Node.js Framework
Kitchen logoKitchen-Sketch Toolkit
Galacean logoGalacean-Interactive Graphics Solution
xtech logoAnt Financial Experience Tech
Theme Editor
Made with ❤ by
Ant Group and Ant Design Community
loading

During the form development process, there are occasional needs for combining attributes. The UI display fields are different from the backend data structure fields. For example, when interfacing with the backend, the province and city fields are often defined as two separate fields { province: Beijing, city: Haidian }, rather than a combined one { province: [Beijing, Haidian] }. Therefore, it is necessary to handle the values in initialValues and onFinish as follows:

import React from 'react';
import { Cascader, Form } from 'antd';
const data = { province: 'Beijing', city: 'Haidian' };
const options = [
{ value: 'zhejiang', label: 'Zhejiang', children: [{ value: 'hangzhou', label: 'Hangzhou' }] },
{ value: 'jiangsu', label: 'Jiangsu', children: [{ value: 'nanjing', label: 'Nanjing' }] },
];
const createUser = (values) => console.log(values);
const Demo = () => (
<Form
initialValues={{ province: [data.province, data.city] }}
onFinish={(values) => {
const { province, ...rest } = values;
createUser({ province: province[0], city: province[1], ...rest });
}}
>
<Form.Item label="Address" name="province">
<Cascader options={options} placeholder="Please select" />
</Form.Item>
</Form>
);
export default Demo;

Encapsulating Aggregate Field Components

When the form is relatively simple, it's manageable, but when encountering a Form.List scenario, it becomes necessary to process the values using map, which can become quite complex. Therefore, we need to encapsulate an aggregated field component to enable a single Form.Item to handle multiple name attributes.

Approach Summary

To implement the aggregation field functionality, we need to utilize getValueProps, getValueFromEvent, and transform to facilitate the transformation of data from FormStore and to re-insert the structure into FormStore upon change.

getValueProps

By default, Form.Item passes the field value from FormStore as the value prop to the child component. However, with getValueProps, you can customize the props that are passed to the child component to implement transformation functionality. In an aggregation scenario, we can iterate through names and combine the values from FormStore into a single value that is then passed to the child component:

getValueProps={() => ({ value: names.map((name) => form.getFieldValue(name)) })}

getValueFromEvent

When the child component modifies the value, the setFields method is used to set the aggregated value returned by the child component to the corresponding name, thereby updating the values of names in FormStore:

getValueFromEvent={(values) => {
form.setFields(names.map((name, index) => ({ name, value: values[index] })));
return values[0];
}}

transform

In rules, the default provided value for validation originates from the value passed to the corresponding name when the child component changes. Additionally, it is necessary to retrieve the values of names from FormStore and use the transform method to modify the value of rules:

rules={[{
transform: () => {
const values = names.map((name) => form.getFieldValue(name));
return values;
},
}]}

Final Result

Summary

By doing so, we have implemented a feature that allows for operating multiple names within a Form.Item, making the form logic clearer and easier to maintain.

In addition to the Cascader example in the text, it is also applicable to components such as DatePicker.RangePicker. In other words, this method can be used in any scenario that requires the aggregation of multiple fields.

Additionally, there are some edge cases in this example that have not been considered. For instance, setFields([{ name:'city', value:'nanjing' }]) will not update the selected value of Cascader. To achieve a refresh effect, you need to add Form.useWatch(values => resetNames.map(name => get(values, name)), form);.

Feel free to explore more edge cases and handle them as needed.

codepen icon
External Link Icon
expand codeexpand code
Beijing / Haidian
Please select