在reactjs中提交后Antd清除表单

Posted

技术标签:

【中文标题】在reactjs中提交后Antd清除表单【英文标题】:Antd clear form after submit in reactjs 【发布时间】:2020-12-12 18:36:42 【问题描述】:

我正在使用 antd 模板进行表单设计。提交表单后输入值没有被清除。

我试过 this.props.form.resetFields() 它没有工作得到以下错误

Unhandled Rejection (TypeError): Cannot read property 'resetFields' of undefined

codesandbox.io/s/funny-wright-oyd72?file=/src/App.js

import React,  Component, useState  from 'react';
import PropTypes from 'prop-types';
import 
    Form,
    Input, Layout,
    Divider,
    Tooltip,
    Cascader,
    Select,
    Row,
    Col,
    Checkbox,
    Button,
    AutoComplete, InputNumber, DatePicker,
 from 'antd';
import axios from 'axios';
import  withRouter  from "react-router-dom";
import moment from 'moment';
import  QuestionCircleOutlined  from '@ant-design/icons';
import countries from './countrys.json'
import SweetAlert from 'sweetalert-react';
import 'sweetalert/dist/sweetalert.css';


const  TextArea  = Input;
const  Option  = Select;
const  Header, Content  = Layout;
const form = Form
class Registration extends Component 

    constructor(props) 
        super(props);
        this.state = 
            customerName: "",
            username: "",
            password: "",
            address: "",
            country: "",
            state: "",
            email: "",
            contactNumber: null,
            dob: "",
            customerAge: null,
            citizenStatus: "",
            accountType: "",
            branchName: "",
            initDepositAmount: null,
            initProofType: "",
            initDocumentNo: "",
            stateList: []
        
      

    

    // handle change text
    handleChangeText = (value, name) => 
        this.setState( [name]: value , () => 
            if (name == 'dob') 
                this.handleChange_age(value)
            
        )
    

    handleChangeCountry = (countryName) => 
        let countrList = countries.countries;
        let countryObject = countrList.find(k => k.country == countryName);
        this.setState(
            ...this.state,
            stateList: countryObject.states,
            country: countryName
        )
    

    //submit form
    submitForm = () => 
        const  stateList, ...withoutStateList  = this.state;
        axios(
            method: 'post',
            url: 'http://localhost:3333/registration',
            data: withoutStateList
          ).then(response => 
            this.setState( 
                show: true 
            );
           // this.props.form.resetFields();
        )
    

    // Cancel form
    navigateToLogin = () => 
        this.props.history.push( pathname: '/login' )
    

    //Check age and Citizen status
    handleChange_age = (dob) => 
        let currentAge = Math.abs((moment().year()) - (moment(dob, "DD/MM/YYYY").year()));
        let statusOfcitizen = null;
        if (currentAge < 18) 
            statusOfcitizen = "Minor";
         else if (currentAge > 18 && currentAge <= 60) 
            statusOfcitizen = "Normal";
         else if (currentAge > 60) 
            statusOfcitizen = "Senior";
        
        this.setState(
            ...this.state,
            customerAge: currentAge,
            citizenStatus: statusOfcitizen
        )
    

    render() 
        const formItemLayout = 
            labelCol: 
                xs:  span: 24 ,
                sm:  span: 9 ,
            ,
            wrapperCol: 
                xs:  span: 24 ,
                sm:  span: 6 ,
            ,
        ;
        const tailFormItemLayout = 
            wrapperCol: 
                xs:  span: 24, offset: 0, ,
                sm:  span: 21, offset: 0, ,
            ,
        ;
        function disabledDate(current) 
            return current && current > moment().endOf('day');
        
        return (
            <div>
                <Divider>New Registration</Divider>
                <Form
                    ...formItemLayout
                    name="register"
                    scrollToFirstError
                    onFinish=() => this.submitForm()
                    ref=this.formRef
                >

                    <Form.Item
                        name="customerName"
                        label="Name"
                        rules=[
                            
                                required: true,
                                message: 'Please input your name!',
                                whitespace: true
                            , 
                                pattern: /^([a-z]+\s)*[a-z]+$/,
                                message: 'Please input alphabets only!',
                            
                        ]
                    >
                        <Input onChange=e => this.handleChangeText(e.target.value, "customerName") />
                    </Form.Item>

                    <Form.Item
                        name="username"
                        label="Username"
                        rules=[
                            
                                required: true,
                                message: 'Please input your username!',
                                whitespace: true,
                            ,
                        ]
                    >
                        <Input onChange=e => this.handleChangeText(e.target.value, "username") />
                    </Form.Item>

                    <Form.Item
                        name="password"
                        label="Password"
                        rules=[
                            
                                required: true,
                                message: 'Please input your password!',
                            ,
                        ]
                    >
                        <Input.Password onChange=e => this.handleChangeText(e.target.value, "password") />
                    </Form.Item>

                    <Form.Item
                        name="address"
                        label="Address"
                        rules=[
                            
                                required: true,
                                message: 'Please input your Address!',
                                whitespace: true,
                            ,
                        ]
                    >
                        <TextArea onChange=e => this.handleChangeText(e.target.value, "address") />
                    </Form.Item>


                    <Form.Item
                        name="country"
                        label="Country"
                        rules=[
                            
                                required: true,
                                message: 'Please input your Country!'
                            ,
                        ]
                    >
                        <Select
                            showSearch
                            placeholder="Select a country"
                            optionFilterProp="children"
                            onChange=e => this.handleChangeCountry(e)
                            filterOption=(input, option) =>
                                option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                            
                        >
                            
                                countries.countries.map((cname, i) => 
                                    return (
                                        <Option value=cname.country key=i>cname.country</Option>
                                    )
                                )
                            
                        </Select>
                    </Form.Item>

                    <Form.Item
                        name="state"
                        label="State"
                        rules=[
                            
                                required: true,
                                message: 'Please input your State!'
                            ,
                        ]
                    >
                        <Select
                            showSearch
                            placeholder="Select a state"
                            optionFilterProp="children"
                            onChange=e => this.handleChangeText(e, "state")
                            filterOption=(input, option) =>
                                option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                            
                        >
                            
                                this.state.stateList.map((sname, i) => 
                                    return (
                                        <Option value=sname key=i>sname</Option>
                                    )
                                )
                            
                        </Select>
                    </Form.Item>

                    <Form.Item
                        name="email"
                        label="E-mail"
                        rules=[
                            
                                type: 'email',
                                message: 'The input is not valid E-mail!',
                            ,
                            
                                required: true,
                                message: 'Please input your E-mail!',
                            ,
                        ]
                    >
                        <Input onChange=e => this.handleChangeText(e.target.value, "email") />
                    </Form.Item>

                    <Form.Item
                        name="contactNumber"
                        label="Contact Number"
                        // validateStatus=this.state.validateStatus
                        // help=this.state.errorMsg
                        rules=[
                            
                                required: true,
                                message: 'Please input your contact number!',
                                type: 'number'

                            ,
                            
                                pattern: /^[2-9]2[0-9]8$/,
                                message: 'Please input valid contact number!',
                            
                        ]
                    >

                        <InputNumber
                            min=0
                            style= width: '100%' 
                            onChange=e => this.handleChangeText(e, "contactNumber")
                        />
                    </Form.Item>


                    <Form.Item
                        name="dob"
                        label="Date Of Birth"
                        rules=[
                            
                                required: true,
                                message: 'Please input your date of birth!'
                            ,
                        ]
                    >
                        <DatePicker
                            format="DD/MM/YYYY"
                            disabledDate=disabledDate
                            style= width: '100%' 
                            onChange=e =>
                                this.handleChangeText(moment(e).format("DD/MM/YYYY"), "dob")
                            
                        />
                    </Form.Item>

                    <Form.Item
                        name="currentAge"
                        label="Your age is"
                    >
                        <Input value=this.state.customerAge disabled />
                        <span></span>
                    </Form.Item>


                    <Form.Item
                        name="citizenStatus"
                        label="Citizen Status"
                    >
                        <Input value=this.state.citizenStatus disabled />
                        <span></span>
                    </Form.Item>

                    <Form.Item
                        name="accountType"
                        label="Account Type"
                        rules=[
                            
                                required: true,
                                message: 'Please input your account type!'
                            ,
                        ]
                    >
                        <Select
                            showSearch
                            placeholder="Select a account type"
                            optionFilterProp="children"
                            filterOption=(input, option) =>
                                option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                            
                            onChange=e => this.handleChangeText(e, "accountType")
                        >
                            <Option value="salary">Salary</Option>
                            <Option value="saving">Saving</Option>
                        </Select>

                    </Form.Item>
                    <Form.Item
                        name="branchName"
                        label="Branch Name"
                        rules=[
                            
                                required: true,
                                message: 'Please input your branch name!',
                                whitespace: true,
                            ,
                        ]
                    >
                        <Input onChange=e => this.handleChangeText(e.target.value, "branchName") />
                    </Form.Item>

                    <Form.Item
                        name="initDepositAmount"
                        label="Initial Deposit Amount"
                        rules=[
                            
                                required: true,
                                message: 'Please input your Initial Deposit Amount!'
                            ,
                        ]
                    >
                        <InputNumber
                            min=1
                            style= width: '100%' 
                            onChange=e => this.handleChangeText(e, "initDepositAmount")
                        />
                    </Form.Item>

                    <Form.Item
                        name="initProofType"
                        label="Identiication Proof Type"
                        rules=[
                            
                                required: true,
                                message: 'Please input your Identiication Proof Type!',
                                whitespace: true,
                            ,
                        ]
                    >
                        <Input onChange=e => this.handleChangeText(e.target.value, "initProofType") />
                    </Form.Item>

                    <Form.Item
                        name="initDocumentNo"
                        label="Identiication Document No"
                        rules=[
                            
                                required: true,
                                message: 'Please input your Identiication Document No!',
                                whitespace: true,
                            ,
                        ]
                    >
                        <Input onChange=e => this.handleChangeText(e.target.value, "initDocumentNo") />
                    </Form.Item>

                    <Form.Item ...tailFormItemLayout>
                        <Button type="primary" htmlType="submit">
                            Register
                        </Button>
                        <Button type="default" style= margin: '0 8px'  onClick=this.navigateToLogin>
                            Cancel
                        </Button>
                    </Form.Item>
                </Form>
                <SweetAlert
                    show=this.state.show
                    title="Done"
                    text="Registered Successfully"
                    success
                    onConfirm=() => this.setState( show: false )
                />
            </div>
        );
    


Registration.propTypes = 

;

export default withRouter(Registration);

【问题讨论】:

是时候继续对钩子做出反应了,伙计。为什么还要使用类组件? 代替this.props.form.resetFields() 再次声明具有空字段的相同变量。它应该可以工作。 【参考方案1】:

首先你不需要使用this.props。当您像这样导入时。如果你还需要 props 的形式,你需要 Form.create ant 的 api。 form 没有从 Form api 导出。更好的方法是你已经定义了 ref。通过它访问表单值:

    定义参考
  formRef = React.createRef();
    传入 formRef 对象:
<Form
          ...formItemLayout
          name="register"
          scrollToFirstError
          onFinish=() => this.submitForm()
          ref=this.formRef
        >
    访问表单值并使用它来重置您的字段:
  //submit form
  submitForm = () => 
    console.log("Form submitted:", this.formRef, Form);
    this.formRef.current.resetFields();
  ;

更新沙盒链接:

https://codesandbox.io/s/admiring-noether-71cnt?file=/src/App.js:1302-1439

【讨论】:

我都尝试了,但出现以下错误 Unhandled Rejection (TypeError): Cannot read property 'resetFields' of undefined 您能否将此代码更新为代码沙箱或检查 console.log 中的值。那里发生了一些小错误 codesandbox.io/s/funny-wright-oyd72?file=/src/App.js【参考方案2】:

更改密钥将使其重新挂载(重新加载初始值):

<Form key=this.state.formKey/>

然后重置它:

this.setState(formKey: (this.state.formKey || 0) + 1)

【讨论】:

以上是关于在reactjs中提交后Antd清除表单的主要内容,如果未能解决你的问题,请参考以下文章

用ant-design在react js中提交后清除表单输入字段值

在 React 中提交表单后无法清除输入字段

React - 表单提交后清除输入值

关于antd如何在表单外点击触发表单验证的问题

【React】antd的form表单的自定义校验规则的用法

antd 的 form resetFields