需求描述
在一些场景下,需要对某些字段进行编辑。
例如在一个表格中,需要对一个单元格里的数据进行展示和编辑。
有很多种编辑方案:
- 只显示编辑组件,例如这个字段是 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.tsximport { 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: stringname: stringlike: string}const Display: FC<EditData> = (props) => {const { name, like } = propsreturn (<Space direction="vertical"><span>Name: {name}</span><span>Like: {like}</span></Space>)}const Edit: FC<{initialValues: EditDataonSuccess: (newData: EditData) => void}> = (props) => {const { initialValues, onSuccess } = propsconst [visible, setVisible] = useState(false)return (<><div onClick={() => setVisible(true)}><EditTwoTone /></div><Modalvisible={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) => (<EditinitialValues={editData}onSuccess={(newData) => setEditData(newData)}/>)}/>)}
示意图:
[END]
