对模糊和按钮点击进行反应验证



我有多步表单,我想进行所需的输入。验证应该在模糊和点击按钮上进行;下一个";。On blur按预期工作,但我在验证按钮点击时遇到问题。就像下面这样,我不去下一步,无论我是否填写了字段,我都不知道如何解决它。

在一个文件中,我有:

import React, { Component } from 'react';
import PersonalDetails from './PersonalDetails';
import CourseDetails from './CourseDetails';
class Form extends Component {
state = {
step: 1,
firstname: '',
lastname: '',
isError: {
firstName: true,
lastName: true
},
errorMessage: {
firstName: '',
lastName: ''
}
};
nextStep = () => {
const { step } = this.state;
this.setState({
step: step + 1
})
}

handleChange = input => e => {
this.setState({
[input]: e.target.value
})
if (input === 'firstname') {
if (this.state.firstname.length >= 1) {
this.setState({
isError: {...this.state.isError, firstName: false}
})
}
}
else if (input === 'lastname') {
if (this.state.lastname.length >= 1) {
this.setState({
isError: {...this.state.isError, lastName: false}
})
}
}
}
validateFirstName = () => {
if (this.state.firstname.length < 2) {
this.setState({
errorMessage: {...this.state.errorMessage, firstName: 'Type your first name (at least 2 characters)'},
isError: {...this.state.isError, firstName: true}
});
}
}
validateLastName = () => {
if (this.state.lastname.length < 2) {
this.setState({
errorMessage: {...this.state.errorMessage, lastName: 'Type your last name (at least 2 characters)'},
isError: {...this.state.isError, lastName: true}
});
}
} 
render() {
const {
step,
firstname,
lastname,
errorMessage,
isError
} = this.state;

switch(step) {
case 1: 
return (
<PersonalDetails 
nextStep={this.nextStep}
handleChange={this.handleChange}
firstname={firstname}
lastname={lastname}
validateFirstName={this.validateFirstName}
validateLastName={this.validateLastName}
errorMessage={errorMessage}
isError={isError}
/>
)
case 2:
return (
<CourseDetails />
)
default: return null
}
}
}
export default Form;

在其他文件中:

class PersonalDetails extends Component {
continue = e => {
e.preventDefault(); 
this.props.validateFirstName();
this.props.validateLastName();
if (!this.props.isError.firstName && !this.props.isError.lastName) {
this.props.nextStep();
}
}
render() {
const { 
firstname, 
lastname, 
handleChange, 
validateFirstName,
validateLastName,
errorMessage,
isError
} = this.props;
return (
<div>
<form>
<div>
<div>
<label htmlFor='first name'>
First name
</label>
<input type='text' value={firstname} name='first name' onChange={handleChange('firstname')} onBlur={validateFirstName} />
<p>{isError.firstName && errorMessage.firstName}</p>
</div>
<div>
<label htmlFor='last name'>
Last name
</label>
<input type='text' value={lastname} name='last name' onChange={handleChange('lastname')} onBlur={validateLastName} />
<p>{isError.lastName && errorMessage.lastName}</p>
</div>

<div>
<button onClick={this.continue}>Next</button>
</div>
</form>
</div>
)
}
}
export default PersonalDetails;

课程详情让我们假设它现在是空页面:

class CourseDetails extends Component {
render() {
return (
<div>

</div>
)
}
}
export default CourseDetails;

由于React状态更新是异步的(不会立即应用(,因此在执行验证后道具不会立即更改。最简单的方法是从验证器返回验证结果,如下所示:

validateFirstName = () => {
if (this.state.firstname.length < 2) {
this.setState({
errorMessage: {...this.state.errorMessage, firstName: 'Type your first name (at least 2 characters)'},
isError: {...this.state.isError, firstName: true}
});
return false;
}
return true;
}
validateLastName = () => {
if (this.state.lastname.length < 2) {
this.setState({
errorMessage: {...this.state.errorMessage, lastName: 'Type your last name (at least 2 characters)'},
isError: {...this.state.isError, lastName: true}
});
return false;
}
return true;
} 

然后你可以用它来确定你是否应该继续下一步:

continue = e => {
e.preventDefault(); 
const isFirstNameValid = this.props.validateFirstName();
const isLastNameValid = this.props.validateLastName();
if (isFirstNameValid && isLastNameValid) {
this.props.nextStep();
}
}

我会尝试不同的方法。我将提取验证本身,并将其用于单一责任,而不是调用validate函数,然后立即尝试检查错误。看看你当前的代码:

continue = e => {
e.preventDefault(); 
this.props.validateFirstName(); // You set / clear the errors in Form state
this.props.validateLastName(); // You set / clear the errors in Form state
if (!this.props.isError.firstName && !this.props.isError.lastName) { // You expect to have that exact state which you've just updated in 2 lines above
this.props.nextStep();
}
}

this.props.isError不会在您刚刚调用了另外2个更新它的函数的函数中立即更新。这在该函数的第二次调用中会很明显。

让我们试着像这样切换:

continue = e => {
e.preventDefault();
if (firstname.length < 2 || lastname.length < 2) {
this.props.validateFirstName();
this.props.validateLastName();
} else {
this.props.nextStep();
}
}

这种方法还需要添加firstnamelastname道具。

最新更新