Open dengfuping opened 6 years ago
antd
Form
getFieldDecorator
onChange
value
Input
TextArea
Select
表单控件
FormTable
收集子节点值的触发事件
子节点值的属性名称
trigger
valuePropName
$ mkdir demo-form-table && cd demo-form-table $ yarn create umi
components/FormTable.js
import React from 'react'; import { Table } from 'antd'; class FormTable extends React.Component { constructor(props) { super(props); } render () { return ( <Table { ...this.props }/> ); } } export default FormTable;
rowSelection
selectedRowKeys
render() { const { selectedRowKeys } = this.state; const rowSelection = { selectedRowKeys, onChange: this.handleSelectChange, }; const newProps = { ...this.props, rowSelection, } return ( <Table {...newProps} /> ); }
handleSelectChange
rowSelection.onChange
handleSelectChange = selectedRowKeys => { const { onChange } = this.props; if (onChange) { onChange(selectedRowKeys); } };
选中项
static getDerivedStateFromProps(props) { const newState = { prevProps: props, }; const { value } = props; if ('value' in props) { // 将下发的 value 赋值给 FormTable,这里将 selectedRowKeys 作为 FormTable 的值 newState.selectedRowKeys = value; } return newState; }
page/index.js
import React from 'react'; import { Form } from 'antd'; import FormTable from '../components/FormTable'; import styles from './index.css'; const FormItem = Form.Item; class IndexPage extends React.Component { render() { const { form: { getFieldDecorator, getFieldValue } } = this.props; const columns = [{ title: 'Name', dataIndex: 'name', render: text => <a href="javascript:;">{text}</a>, }, { title: 'Age', dataIndex: 'age', }, { title: 'Address', dataIndex: 'address', }]; const dataSource = [{ key: '1', name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park', }, { key: '2', name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park', }, { key: '3', name: 'Joe Black', age: 32, address: 'Sidney No. 1 Lake Park', }, { key: '4', name: 'Disabled User', age: 99, address: 'Sidney No. 1 Lake Park', }]; return ( <div className={styles.container}> <Form> <FormItem label="表格表单项"> { getFieldDecorator('selectedRowKeys', {})(<FormTable dataSource={dataSource} columns={columns} />) } </FormItem> </Form> <h4>选中项为: {getFieldValue('selectedRowKeys') && getFieldValue('selectedRowKeys').join(', ')}</h4> </div> ); } } export default Form.create()(IndexPage);
FormTable 只作为一个受控组件来说的话,selectedRowKeys 这个状态是多余的,直接用 this.props.selectedRowKeys 就可以了。
this.props.selectedRowKeys
antd
中的Form
时常会通过getFieldDecorator
来实现数据的双向绑定,可以有效避免去写大量重复的受控代码。其本质是一个高阶函数,会在合适的时机(默认是onChange
事件)自动收集被包装组件的value
。常见组件如Input
、TextArea
、Select
等在Form
中的用法可以参考 Ant Design Demo 用法,本文只介绍如何在Form
中自定义表单控件。表单控件
在中后台业务中很常见,但实际上相当一部分同学都是通过 受控 的方式去处理表格表单的,下面将介绍如何编写一个可复用的FormTable
表单控件。实现原理
onChange
和value
属性,分别用于收集子节点值的触发事件
和子节点值的属性名称
,并且可以通过trigger
和valuePropName
自定义这两个属性。初始化项目
antd
,即可创建项目。编写 FormTable 组件
components/FormTable.js
,初始化如下:rowSelection
属性,这里将selectedRowKeys
作为FormTable
的值:handleSelectChange
函数的作用是通过rowSelection.onChange
函数获取selectedRowKeys
,然后通过下发的onChange
属性函数来收集FormTable
的值:value
维护FormTable
内部的selectedRowKeys
状态,不然无法保留上次的选中项
:测试一下
page/index.js
中测试一下我们刚刚写的FormTable
组件吧!