setState 在表单验证中没有按预期工作
setState not working as expected in the form validations
我对反应有点陌生,我正在尝试实现带有验证的动态表单。我从后端获取输入详细信息并根据它渲染组件。一切正常,但是当我尝试包括表单验证时(当用户提交表单时我想进行表单验证)它根本不起作用。我尝试了网络上的所有解决方案,但没有找到任何解决此问题的方法。谁能帮我解决这个问题?谢谢!!
这是我的代码
class Slider extends Component {
constructor(props) {
super(props)
const { providerConfigs } = this.props
this.state = {
hasError: false,
inputs: [....]
}
}
.....
handleOnSubmit = () => {
this.setState({ hasError: false })
const { providerMappingActions: { addProvider }, history } = this.props;
const { inputs } = this.state;
inputs.forEach(input => {
if (input.isRequired && input.attributeValue.length === 0) {
this.setState({ hasError: true })
}
if (input.attributeOptionId == 5 && input.attributeValue.length !== 0) {
if (input.attributeValue.length !== 10) {
this.setState({ hasError: true })
}
}
})
if (!this.state.hasError) {
const attributes = inputs.map(input => {
return {
attributeName: input.attributeName,
attributeValue: input.attributeValue,
isRequired: input.isRequired,
attributeOptionId: input.attributeOptionId,
}
});
console.log(attributes)
this.resetInputs();
}
}
render() {
const { hasError, inputs } = this.state;
return (
<div>
<div >
<div >
....
</FormGroup>)
: (
<FormGroup key={input.attributeOptionId}>
<FormControl
name={input.attributeName}
type={this.checkType(input.fieldType)}
autoFocus={!input.value}
value={input.value}
onChange={(e) => { this.handleChange(e) }}
className={`${(hasError && input.isRequired && input.attributeValue.length === 0) ? 'validation-field-error' :
hasError && input.attributeOptionId === 5 && input.attributeValue != '' && input.attributeValue.length !== 10 ? 'validation-field-error' : ''}`}
/>
</FormGroup>)
}
</td>
</tr>
);
})
}
<tr>
<td colSpan={2} align='right'>
{
inputs.map(input => {
if (hasError && input.isRequired && input.attributeValue.length === 0) {
return <div
key={input.attributeOptionId}
>
<label className='validation-error-text'><b>{input.attributeName} is required!</b></label>
</div>
} else if (hasError && input.attributeOptionId == 5 && input.attributeValue != '' && input.attributeValue.length !== 10) {
return <div
key={input.attributeOptionId}
>
<label className='validation-error-text'><b>Insert valid {input.attributeName}!</b></label>
</div>
}
}
)
}
</td>
</tr>
</tbody>
</table>
<FormGroup>
<div >
<div style={{ paddingLeft: "20px", paddingRight: "20px" }}>
<button
...
</div>
</FormGroup>
</form>
</div>
</div>
</div>
</div >
)
}}
请注意,我删除了一些代码以提高可读性。
setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall.
设置后立即读取状态并不能保证您期望的结果。重构为一个局部变量,只在函数结束时设置一次状态:
handleOnSubmit = () => {
const hasError = false;
const { providerMappingActions: { addProvider }, history } = this.props;
const { inputs } = this.state;
inputs.forEach(input => {
if (input.isRequired && input.attributeValue.length === 0) {
hasError = true;
}
if (input.attributeOptionId == 5 && input.attributeValue.length !== 0) {
if (input.attributeValue.length !== 10) {
hasError = true;
}
}
})
if (!hasError) {
const attributes = inputs.map(input => {
return {
attributeName: input.attributeName,
attributeValue: input.attributeValue,
isRequired: input.isRequired,
attributeOptionId: input.attributeOptionId,
}
});
console.log(attributes)
this.resetInputs();
}
// Set the state only once at the end of the function, this will
// cause a re-render if the value changes.
this.setState({ hasError });
}
我对反应有点陌生,我正在尝试实现带有验证的动态表单。我从后端获取输入详细信息并根据它渲染组件。一切正常,但是当我尝试包括表单验证时(当用户提交表单时我想进行表单验证)它根本不起作用。我尝试了网络上的所有解决方案,但没有找到任何解决此问题的方法。谁能帮我解决这个问题?谢谢!!
这是我的代码
class Slider extends Component {
constructor(props) {
super(props)
const { providerConfigs } = this.props
this.state = {
hasError: false,
inputs: [....]
}
}
.....
handleOnSubmit = () => {
this.setState({ hasError: false })
const { providerMappingActions: { addProvider }, history } = this.props;
const { inputs } = this.state;
inputs.forEach(input => {
if (input.isRequired && input.attributeValue.length === 0) {
this.setState({ hasError: true })
}
if (input.attributeOptionId == 5 && input.attributeValue.length !== 0) {
if (input.attributeValue.length !== 10) {
this.setState({ hasError: true })
}
}
})
if (!this.state.hasError) {
const attributes = inputs.map(input => {
return {
attributeName: input.attributeName,
attributeValue: input.attributeValue,
isRequired: input.isRequired,
attributeOptionId: input.attributeOptionId,
}
});
console.log(attributes)
this.resetInputs();
}
}
render() {
const { hasError, inputs } = this.state;
return (
<div>
<div >
<div >
....
</FormGroup>)
: (
<FormGroup key={input.attributeOptionId}>
<FormControl
name={input.attributeName}
type={this.checkType(input.fieldType)}
autoFocus={!input.value}
value={input.value}
onChange={(e) => { this.handleChange(e) }}
className={`${(hasError && input.isRequired && input.attributeValue.length === 0) ? 'validation-field-error' :
hasError && input.attributeOptionId === 5 && input.attributeValue != '' && input.attributeValue.length !== 10 ? 'validation-field-error' : ''}`}
/>
</FormGroup>)
}
</td>
</tr>
);
})
}
<tr>
<td colSpan={2} align='right'>
{
inputs.map(input => {
if (hasError && input.isRequired && input.attributeValue.length === 0) {
return <div
key={input.attributeOptionId}
>
<label className='validation-error-text'><b>{input.attributeName} is required!</b></label>
</div>
} else if (hasError && input.attributeOptionId == 5 && input.attributeValue != '' && input.attributeValue.length !== 10) {
return <div
key={input.attributeOptionId}
>
<label className='validation-error-text'><b>Insert valid {input.attributeName}!</b></label>
</div>
}
}
)
}
</td>
</tr>
</tbody>
</table>
<FormGroup>
<div >
<div style={{ paddingLeft: "20px", paddingRight: "20px" }}>
<button
...
</div>
</FormGroup>
</form>
</div>
</div>
</div>
</div >
)
}}
请注意,我删除了一些代码以提高可读性。
setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall.
设置后立即读取状态并不能保证您期望的结果。重构为一个局部变量,只在函数结束时设置一次状态:
handleOnSubmit = () => {
const hasError = false;
const { providerMappingActions: { addProvider }, history } = this.props;
const { inputs } = this.state;
inputs.forEach(input => {
if (input.isRequired && input.attributeValue.length === 0) {
hasError = true;
}
if (input.attributeOptionId == 5 && input.attributeValue.length !== 0) {
if (input.attributeValue.length !== 10) {
hasError = true;
}
}
})
if (!hasError) {
const attributes = inputs.map(input => {
return {
attributeName: input.attributeName,
attributeValue: input.attributeValue,
isRequired: input.isRequired,
attributeOptionId: input.attributeOptionId,
}
});
console.log(attributes)
this.resetInputs();
}
// Set the state only once at the end of the function, this will
// cause a re-render if the value changes.
this.setState({ hasError });
}