需求描述
在一些场景下,需要对某些字段进行编辑。
例如在一个表格中,需要对一个单元格里的数据进行展示和编辑。
有很多种编辑方案:
- 只显示编辑组件,例如这个字段是 string 类型,就直接展示为一个 Input 组件,修改这个组件内容会触发字段更新。
- 在展示组件与编辑组件之间切换。例如这个字段是 string 类型,展示为一个 string 组件,点击后展示为 Input 组件。
- 正常显示展示组件,弹窗展示编辑组件。
在上述方案中,只有方案 3 可以做到展示组件与编辑组件分离,并且弹窗编辑也能支持更多复杂的编辑手段,所以我们选中方案 3 来做。
设计
基本逻辑为:
- 实现一个展示组件。
- 实现一个编辑组件。包括了点击按钮和编辑弹窗。
- 编辑成功后(与后端交互成功),关闭弹窗,并更新展示组件。
实现
```tsx // display-edit.tsx import { Space } from ‘antd’ import React, { Dispatch, ReactElement, useState } from ‘react’
export function DisplayEdit
const [editData, setEditData] = useState(defaultEditData)
return (
```tsx
// page.tsx
import { EditTwoTone } from '@ant-design/icons'
import { Button, Form, Input, Modal, Space } from 'antd'
import React, { FC, useState } from 'react'
import { DisplayEdit } from './display-edit'
type EditData = {
id: string
name: string
like: string
}
const Display: FC<EditData> = (props) => {
const { name, like } = props
return (
<Space direction="vertical">
<span>Name: {name}</span>
<span>Like: {like}</span>
</Space>
)
}
const Edit: FC<{
initialValues: EditData
onSuccess: (newData: EditData) => void
}> = (props) => {
const { initialValues, onSuccess } = props
const [visible, setVisible] = useState(false)
return (
<>
<div onClick={() => setVisible(true)}>
<EditTwoTone />
</div>
<Modal
visible={visible}
onCancel={() => setVisible(false)}
title="Edit"
footer={null}
>
<Form<EditData>
layout="vertical"
initialValues={initialValues}
onFinish={(formValues) => {
onSuccess(formValues)
setVisible(false)
}}
>
<Form.Item label="ID" name="id">
<Input />
</Form.Item>
<Form.Item label="Name" name="name">
<Input />
</Form.Item>
<Form.Item label="Like" name="like">
<Input />
</Form.Item>
<Form.Item>
<Button htmlType="submit" type="primary">
Submit
</Button>
</Form.Item>
</Form>
</Modal>
</>
)
}
export const Page: FC = () => {
return (
<DisplayEdit<EditData>
defaultEditData={{ id: '1', name: 'fy', like: 'code' }}
displayNodeRender={(editData) => <Display {...editData} />}
editNodeRender={(editData, setEditData) => (
<Edit
initialValues={editData}
onSuccess={(newData) => setEditData(newData)}
/>
)}
/>
)
}
示意图:
[END]