赞
踩
在跟着B站React实战课程走的时候,因为课程是Antd V3我使用的是V4。所以在遇到Modal中嵌套From时,课程使用的是高阶组件的方式实现验证器。我看见V4直接有rules(包括使用validator)属性,直接设置后发现无效。
其实在官方文档有Modal组件配合的实例。
import React, { useState } from 'react'; import { Button, Modal, Form, Input, Radio } from 'antd'; interface Values { title: string; description: string; modifier: string; } interface CollectionCreateFormProps { visible: boolean; onCreate: (values: Values) => void; onCancel: () => void; } const CollectionCreateForm: React.FC<CollectionCreateFormProps> = ({ visible, onCreate, onCancel, }) => { const [form] = Form.useForm(); return ( <Modal visible={visible} title="Create a new collection" okText="Create" cancelText="Cancel" onCancel={onCancel} onOk={() => { form .validateFields() .then(values => { form.resetFields(); onCreate(values); }) .catch(info => { console.log('Validate Failed:', info); }); }} > <Form form={form} layout="vertical" name="form_in_modal" initialValues={{ modifier: 'public' }} > <Form.Item name="title" label="Title" rules={[{ required: true, message: 'Please input the title of collection!' }]} > <Input /> </Form.Item> <Form.Item name="description" label="Description"> <Input type="textarea" /> </Form.Item> <Form.Item name="modifier" className="collection-create-form_last-form-item"> <Radio.Group> <Radio value="public">Public</Radio> <Radio value="private">Private</Radio> </Radio.Group> </Form.Item> </Form> </Modal> ); }; const CollectionsPage = () => { const [visible, setVisible] = useState(false); const onCreate = values => { console.log('Received values of form: ', values); setVisible(false); }; return ( <div> <Button type="primary" onClick={() => { setVisible(true); }} > New Collection </Button> <CollectionCreateForm visible={visible} onCreate={onCreate} onCancel={() => { setVisible(false); }} /> </div> ); }; ReactDOM.render(<CollectionsPage />, mountNode); .collection-create-form_last-form-item { margin-bottom: 0; }
CollectionCreateForm 时最关键的部分,这里使用里React的hook语法。我通过一些更改把它还是变成了封装一个类(感觉这样也不好)。
代码如下:
import { Form, Modal } from 'antd'; import React, { Component } from 'react'; import { ICategory } from './DataModel'; import { ModalStatusCode } from './ModalStatusCode'; interface Values { title: string; description: string; modifier: string; } interface ModalFromProps { showStatus: ModalStatusCode; onCancel: () => void; category: ICategory; element: React.ReactNode; expectedStatus: ModalStatusCode; title: string; } interface ModalState { name: string; } class ModalForm extends Component<ModalFromProps, ModalState> { constructor(props: ModalFromProps) { super(props); this.state = { name: '', }; } private onCancel = () => { this.props.onCancel(); }; private CreateModalFrom = (): any => { const [form] = Form.useForm(); const { title } = this.props; return ( <Modal visible={this.props.showStatus === this.props.expectedStatus} title={title} okText="Ok" cancelText="Cancel" onCancel={this.onCancel} onOk={() => { form .validateFields() .then((values) => { form.resetFields(); console.log(values); }) .catch((info) => { console.log('Validate Failed:', info); }); }} > <Form form={form}> <Form.Item name="title" rules={[{ required: true, message: '请输入品类名称' }]} initialValue={this.props.category.name} > {this.props.element} </Form.Item> </Form> </Modal> ); }; render() { return <this.CreateModalFrom />; } }
因为是React新手,所以还是凭着自己理解去封装。这样导致自定义ModalForm组件为了得到某些值必须经过某个中间组件去传,看起来就很难看且值没有任何更改,很难看。希望各位也能给个好建议。
调用ModalForm代码:
interface IUpdateFormProps { category: ICategory; onCancel: () => void; showStatus: ModalStatusCode; } interface IUpdateFormState { } export default class UpdateFrom extends Component<IUpdateFormProps, IUpdateFormState> { render() { return ( <ModalForm {...this.props} element={<Input placeholder="请输入分类名称"></Input>} expectedStatus={ModalStatusCode.Update} title='更新分类'></ModalForm> ); } }
对应页面上有一个列表,列表有一个修改功能。点击之后Form的input框里面显示该行属性名称。但是奇怪的是这样写名称会不更新。始终是第一个点击那一行,尝试后发现点击OK按钮名称会更新。查看代码后发现是
form.resetFields();
起的作用,因此想着每次都调用这个方法,但尝试一番无果。晚上再去看Modal的官方文档后发现这么一句话。
<Modal /> 默认关闭后状态不会自动清空, 如果希望每次打开都是新内容,请设置 destroyOnClose。
<Modal /> 和 Form 一起配合使用时,设置 destroyOnClose 也不会在 Modal 关闭时销毁表单字段数据,
需要设置 <Form preserve={false} />。
于是想着能不能每次打开都是重新渲染,解决这个问题。于是在添加上面的属性后便解决了问题。
虽然解决了问题但是感觉有更好解决方案或者另一种实现方法,如果能还希望不吝赐教。
从偶然的出生,到必然的死亡,我们都将经历孤独和徘徊。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。