直接上index.tsx可以根据官网修改的可以直接运行
import {Form, Input, InputNumber, Popconfirm, Select, Table} from 'antd';
import React from "react";
const {Option} = Select;
const layout = {
labelCol: {span: 8},
wrapperCol: {span: 16},
};
const originData: any = [];
for (let i = 0; i < 100; i++) {
originData.push({
key: i.toString(),
name: `Edrward ${i}`,
age: 32,
address: `London Park no. ${i}`,
});
}
class EditableCell extends React.Component<any, any> {
constructor(props) {
super(props);
}
getInput = () => {
if (this.props.inputType === 'number') {
return <InputNumber/>;
}
return <Input/>;
};
render() {
const {
editing,
dataIndex,
title,
inputType,
record,
index,
children,
...restProps
} = this.props
return (
<td {...restProps}>
{editing ? (
<Form.Item name={dataIndex} label={dataIndex} style={{margin: 0}} rules={[{
required: true,
message: `Please Input ${title}!`,
}]}>
{this.getInput()}
</Form.Item>
) : (
children
)}
</td>
);
}
}
class EditableTable extends React.Component<any, any> {
formRef = React.createRef();
constructor(props) {
super(props);
this.columns = [
{
title: 'name',
dataIndex: 'name',
width: '25%',
editable: true,
},
{
title: 'age',
dataIndex: 'age',
width: '15%',
editable: true,
},
{
title: 'address',
dataIndex: 'address',
width: '40%',
editable: true,
},
{
title: 'operation',
dataIndex: 'operation',
render: (text, record) => {
const {editingKey} = this.props.state;
const editable = this.isEditing(record);
return editable ? (
<span>
<a
onClick={() => this.save(record.key)}
style={{
marginRight: 8,
}}
>
Save
</a>
<Popconfirm title="Sure to cancel?" onConfirm={() => this.cancel(record.key)}>
<a>Cancel</a>
</Popconfirm>
</span>
) : (
<a disabled={editingKey !== ''} onClick={() => this.edit(record)}>
Edit
</a>
);
},
},
];
}
isEditing = record => record.key === this.props.state.editingKey;
edit(record: any) {
this.formRef.current.setFieldsValue({
name: '',
age: '',
address: '',
...record,
});
this.props.handleEdit(record)
};
cancel = () => {
this.props.handleCancel()
};
save(key: any) {
const row = this.formRef.current.getFieldsValue();
const newData = [...this.props.state.data];
const index = newData.findIndex((item) => key === item.key);
if (index > -1) {
const item = newData[index];
newData.splice(index, 1, {...item, ...row});
} else {
newData.push(row);
}
this.props.handleSave(newData)
};
render() {
const components = {
body: {
cell: EditableCell,
},
};
const mergedColumns = this.columns.map(col => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: record => ({
record,
inputType: col.dataIndex === 'age' ? 'number' : 'text',
dataIndex: col.dataIndex,
title: col.title,
editing: this.isEditing(record),
}),
};
});
return (
<Form ref={this.formRef} component={false}>
<Table
components={components}
bordered
dataSource={this.props.state.data}
columns={mergedColumns}
rowClassName="editable-row"
pagination={{
onChange: this.cancel,
}}
></Table>
</Form>
);
}
}
export default class Demo extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = {
data: originData,
editingKey: '',
}
}
handleEdit = (record: any) => {
this.setState({editingKey: record.key});
}
handleCancel = () => {
this.setState({editingKey: ''});
}
handleSave = (newData) => {
this.setState({
data: newData,
editingKey: ''
})
}
render() {
const parentMethods = {
handleEdit: this.handleEdit,
handleCancel: this.handleCancel,
handleSave: this.handleSave,
state: this.state
};
return (
<EditableTable {...parentMethods}/>
// <MyForm/>
)
}
}
注意点1:
传值问题:
子组件修改父组件的state必须 在父组件中定义,然后在子组件使用this.props进行调用父组件的方法,这个方法最后i修改state。
注意点2:
form的使用
v4的class版使用form那是真坑啊,耗费我好几天时间,记录下。
v4中使用form传递的时候
使用下面代替useForm()
formRef = React.createRef();
v4中Form.Item不支持设置默认值,但是这里的场景是需要单独设置的,所以使用
this.formRef.current.setFieldsValue({
name: '',
age: '',
address: '',
...record,
});
设置当前单元格的值
获取当前单元格的值用
const row = this.formRef.current.getFieldsValue();
具体看上面的代码