在这里,我使用的是Redux向导表单(https://redux-form.com/6.3.1/examples/wizard/)。但是我面临一个关于验证错误的问题。在它的步骤下面。
第1步
在此步骤中,当我填写我的字段(campaign_name,start_date和end_date),然后按“继续”按钮时,它工作正常。
第二步
在这里,当我直接单击“下一步”按钮时,它会显示我在此处设置的验证错误消息。
但是问题是,在执行完上述两个步骤并从左侧菜单中单击任何其他部分之后,再次出现在步骤2中,验证错误消息仍然存在,这是我所不希望的。意味着它是在单击“下一步”按钮之后出现的,如果任何字段为空,则只会出现验证错误。
在这里,我还附加了视频URL,还附加了一些相同的屏幕截图。请检查一次,这样您会更好的主意。 网址:https://www.screencast.com/t/A15tavAL73i
主要组件:Campaign.jsx
import React, { Component } from 'react';
import FormStep1 from '../components/Campaign/FormStep1';
import FormStep2 from '../components/Campaign/FormStep2';
import { Link, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { createCampaign } from '../actions/campaign';
import { routeCodes } from '../constants/routes';
import { reset, initialize, untouch } from 'redux-form';
class Campaign extends Component {
constructor(props) {
super(props);
this.nextPage = this.nextPage.bind(this);
this.previousPage = this.previousPage.bind(this);
this.state = {
page: 1,
};
this.submitForm = this.submitForm.bind(this);
}
nextPage() { this.setState({ page: this.state.page + 1 }) }
previousPage() { this.setState({ page: this.state.page - 1 }); }
changePage = (pageNo) => { this.setState({ page: pageNo }); }
componentWillUnmount() {
const { dispatch } = this.props;
this.props.dispatch(untouch('wizardCampaign','call_to_action'));
dispatch(initialize('wizardCampaign', {}))
dispatch(reset('wizardCampaign'));
}
submitForm(values, actionGenerator, props) {
console.log('values');
}
render() {
const { onSubmit, loading } = this.props;
const { page } = this.state;
return (
<div className='Campaign'>
{page === 1 && <FormStep1
onSubmit={this.nextPage} changePage={this.changePage}
multipleImagesFun={this.multipleImagesFun}
prevImg={this.state.multipleImages}
/>}
{page === 2 && <FormStep2
changePage={(i) => this.changePage(i)}
previousPage={this.previousPage}
onSubmit={this.nextPage}
multipleImagesFun={this.multipleImagesFun}
prevImg={this.state.multipleImages}
/>}
</div>
);
}
}
const mapStateToProps = (state) => {
const { campaign } = state;
return {
loading: campaign.get('loading'),
error: campaign.get('error'),
campaign: campaign.get('campaign')
}
}
export default connect(mapStateToProps)(Campaign)
子组件:步骤-1
import React, { Component } from 'react';
import FormCampaignRight from './FormCampaignRight';
import { CommonCompo } from './CommonCompo';
import { Field, reduxForm } from 'redux-form';
import moment from 'moment';
import { renderFieldCampaign, renderFieldDatePicker } from '../../components/Forms/RenderFormComponent/EveryComponent';
import { reset, initialize } from 'redux-form';
const validate = values => {
const errors = {};
if (!values.campaignName || (values.campaignName !== undefined && values.campaignName.trim() == "")) {
errors.campaignName = 'This field is required';
} else if(values.campaignName.length > 25){
errors.campaignName = 'Max. character length is 25';
}
if (!values.campaignStartDate) { errors.campaignStartDate = 'This field is required'; }
if (!values.campaignEndDate) { errors.campaignEndDate = 'This field is required'; }
if (values.campaignStartDate && values.campaignEndDate) {
let a = moment(values.campaignStartDate);
let b = moment(values.campaignEndDate);
let diffDate = b.diff(a);
if (diffDate < 0) {
errors.campaignEndDate = 'End date should be after start date';
}
}
return errors;
};
class FormStep1 extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { handleSubmit,prevImg } = this.props;
return (
<form onSubmit={handleSubmit}>
<div className="right-box create-campaign d-flex">
<div className="create-campaign-l d-flex">
<CommonCompo currentPage="1" changePage={(i) => this.props.changePage(i)} />
<div className="step-content d-flex">
<h2>Step 1</h2>
<Field
name="campaignName"
type="text"
label="Campaign Name"
component={renderFieldCampaign}
placeholder="Campaign Name"
isRequired="true"
/>
<Field
name="campaignStartDate"
label="Date of Campaign Start"
component={renderFieldDatePicker}
className="campiagn_date"
defaultValue={moment()}
showDisabledMonthNavigation
minDateVal={moment()}
placeholder="Campaign start date"
isRequired="true"
/>
<Field
name="campaignEndDate"
label="Date of Campaign End"
component={renderFieldDatePicker}
className="campiagn_date"
defaultValue={null}
showDisabledMonthNavigation
placeholder="Campaign end date"
isRequired="true"
/>
<div className="submit-btn">
<button type="submit" className="round-btn next-btn">Continue</button>
</div>
</div>
</div>
<FormCampaignRight existImages = {prevImg} />
</div>
</form>
);
}
}
export default reduxForm({
form: 'wizardCampaign',
destroyOnUnmount: false,
forceUnregisterOnUnmount: true,
validate,
})(FormStep1);
子组件:步骤-2
import React,{Component} from 'react';
import FormCampaignRight from './FormCampaignRight';
import {CommonCompo} from './CommonCompo';
import { Field, reduxForm } from 'redux-form';
import DatePicker from 'react-datepicker';
import validator from 'validator';
import moment from 'moment';
import {renderFieldCampaign,renderFieldDatePicker,SelectField_ReactSelect,SelectField_ReactSelectMulti} from '../../components/Forms/RenderFormComponent/EveryComponent';
const validate = values => {
const errors = {};
var regexp = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/; // fragment locater
if (!values.call_to_action || (values.call_to_action!==undefined && values.call_to_action.trim()=="")) {
errors.call_to_action = 'This field is required';
} else if(!regexp.test(values.call_to_action)) {
errors.call_to_action = 'Please enter valid URL';
}
if (!values.discount_code || (values.discount_code!==undefined && values.discount_code.trim()=="")) { errors.discount_code = 'This field is required'; }
if (!values.short_desc || (values.short_desc!==undefined && values.short_desc.trim()=="")) { errors.short_desc = 'This field is required'; }
if (!values.industryName || (values.industryName!==undefined && values.industryName.value==="")) { errors.industryName = 'This field is required'; }
if(!values.tagHash || (values.tagHash!==undefined && values.tagHash=="")){ errors.tagHash = 'This field is required'; }
if(!values.tagAt || (values.tagAt!==undefined && values.tagAt=="")){ errors.tagAt = 'This field is required'; }
return errors;
};
class FormStep2 extends Component{
constructor(props){
super(props);
}
render(){
const { handleSubmit,previousPage,prevImg } = this.props;
return(
<form onSubmit={handleSubmit}>
<div className="right-box create-campaign d-flex">
<div className="create-campaign-l d-flex">
<CommonCompo currentPage="2" changePage={(i) => this.props.changePage(i)}/>
<div className="step-content d-flex">
<h2>Step 2</h2>
<Field
name="call_to_action"
type="text"
label="Call to action"
component={renderFieldCampaign}
placeholder="www.example.com"
isRequired="true"
/>
<Field
name="discount_code"
type="text"
label="Discount Code"
component={renderFieldCampaign}
placeholder="Discount Code"
isRequired="true"
/>
<Field
name="short_desc"
type="text"
label="Short Description"
component={renderFieldCampaign}
placeholder="Short Description"
isRequired="true"
/>
<Field
className="campaign_form_step2_dropdown "
wrapperClass="select-wrap"
name="industryName"
label="Social media platforms"
labelClass="control-label"
placeholder="Social media platforms"
component={SelectField_ReactSelect}
options={[
{ value: '' , label :"Select social media"},
{ value: 'facebook' , label :"Facebook"},
{ value: 'instagram' , label :"Instagram"},
{ value: 'twitter' , label :"Twitter"},
{ value: 'pinterest' , label :"Pinterest"},
{ value: 'linkedin' , label :"Linkedin"},
]}
isRequired="true"
/>
<Field
name="tagHash"
label="# tags"
labelClass="control-label"
wrapperClass="select-wrap tag-1"
placeholder="# tags"
component={SelectField_ReactSelectMulti}
className="campaign_form_step2_dropdown txt_tag"
isRequired="true"
/>
<Field
name="tagAt"
label="@ tags"
labelClass="control-label"
wrapperClass="select-wrap tag-2"
placeholder="@ tags"
component={SelectField_ReactSelectMulti}
className="campaign_form_step2_dropdown txt_tag"
isRequired="true"
/>
<div className="submit-btn d-flex">
<button type="button" onClick={previousPage}
className="round-btn prev-btn">Previous</button>
<button type="submit" className="round-btn next-btn">Next</button>
</div>
</div>
</div>
<FormCampaignRight existImages = {prevImg} />
</div>
</form>
);
}
}
export default reduxForm({
form: 'wizardCampaign',
destroyOnUnmount: false,
forceUnregisterOnUnmount: true,
validate,
})(FormStep2);
我该如何进行?