ReactJS 使用 MaterialUI 处理表单错误
ReactJS Handling Form Errors With MaterialUI
提交表单后,我想验证两个字段。具体来说,我想检查密码是否至少有 5 个字符,以及 password 和 confirmPassword 字段是否匹配。我继续实施状态来保存这些错误消息。但是,并不是所有的错误都被显示出来。示例:假设用户在密码字段中输入了 'hell',并在密码确认中输入了 'hello'。您可能会收到 2 条错误消息(密码太短,密码不匹配),但我的表单只显示一条错误 - 密码不匹配。
我怀疑问题出在 validateFields 函数上。如果我交换 if 语句的顺序并输入我上面描述的相同输入,那么我设法看到 'password must contain at least 5 characters' 错误,但看不到“密码不匹配错误”。此外,在使用反应开发工具时,我注意到在错误状态下只设置了一条消息。所以我认为我没有正确使用 setState,也许传播运算符没有按我的预期工作?
import React, {useState} from 'react'
import {Grid, TextField, RadioGroup, Radio, FormControl, FormLabel, FormControlLabel, Checkbox, Button} from '@material-ui/core'
const Registration = () => {
const [data, setData] = useState({
username: '',
email: '',
password: '',
confirmPassword: '',
})
const [errors, setErrors] = useState({
short: '',
mismatch: '',
})
const handleChange = e => {
const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value
setData({
...data,
[e.target.name]: value,
})
}
const validateFields = () => {
let error = false
if (data.password && data.password.length < 5) {
error = true
console.log('password was too short')
setErrors({...errors, short: 'Password must contain at least 5 characters'})
console.log('short set')
}
if (data.confirmPassword && data.confirmPassword !== data.password) {
error = true
setErrors({...errors, mismatch: "Passwords don't match"})
}
return error
}
const handleSubmit = e => {
e.preventDefault()
console.log(data)
if (validateFields()) {
return
}
}
return (
<Grid id='registration-form' container xs={12} direction='column'>
<Grid item xs={12} align='center'>
<h1>Register</h1>
</Grid>
<form onSubmit={handleSubmit}>
<Grid container spacing={2} xs={12} alignItems='center' justify='center'>
<Grid container item xs={3} direction='column' spacing={2}>
<Grid item>
<TextField id='username' name='username' label='Username' onChange={handleChange} value={data.username} required />
</Grid>
<Grid item>
<TextField id='email' name='email' label='Email' onChange={handleChange} value={data.email} required type='email' />
</Grid>
<Grid item>
<TextField id='password' name='password' label='Password' onChange={handleChange} value={data.password} error={errors.short !== ''} helperText={errors.short} required type='password' />
</Grid>
<Grid item>
<TextField
id='confirm-password'
name='confirmPassword'
label='Confirm Password'
onChange={handleChange}
value={data.confirmPassword}
error={Boolean(errors?.mismatch)}
helperText={errors?.mismatch}
required
type='password'
/>
</Grid>
</Grid>
</Grid>
</form>
<Grid item align='center'>
<a href='#'>Already have an account? Login</a>
</Grid>
</Grid>
)
}
export default Registration
通过以下代码更改您的验证函数。它会起作用。
const validateFields = () => {
let error = false
if (data.password && data.password.length < 5) {
error = true
console.log('password was too short')
//notice updater function here
setErrors(state=>({...state, short: 'Password must contain at least 5 characters'}))
console.log('short set')
}
if (data.confirmPassword && data.confirmPassword !== data.password) {
error = true
setErrors(state=>({...state, mismatch: "Passwords don't match"}))
}
return error
}
当您的状态更新取决于以前的状态值时,传递函数而不是对象来设置状态,以确保调用始终使用状态的最新版本。
传递更新函数允许您访问更新程序内部的当前状态值。
提交表单后,我想验证两个字段。具体来说,我想检查密码是否至少有 5 个字符,以及 password 和 confirmPassword 字段是否匹配。我继续实施状态来保存这些错误消息。但是,并不是所有的错误都被显示出来。示例:假设用户在密码字段中输入了 'hell',并在密码确认中输入了 'hello'。您可能会收到 2 条错误消息(密码太短,密码不匹配),但我的表单只显示一条错误 - 密码不匹配。
我怀疑问题出在 validateFields 函数上。如果我交换 if 语句的顺序并输入我上面描述的相同输入,那么我设法看到 'password must contain at least 5 characters' 错误,但看不到“密码不匹配错误”。此外,在使用反应开发工具时,我注意到在错误状态下只设置了一条消息。所以我认为我没有正确使用 setState,也许传播运算符没有按我的预期工作?
import React, {useState} from 'react'
import {Grid, TextField, RadioGroup, Radio, FormControl, FormLabel, FormControlLabel, Checkbox, Button} from '@material-ui/core'
const Registration = () => {
const [data, setData] = useState({
username: '',
email: '',
password: '',
confirmPassword: '',
})
const [errors, setErrors] = useState({
short: '',
mismatch: '',
})
const handleChange = e => {
const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value
setData({
...data,
[e.target.name]: value,
})
}
const validateFields = () => {
let error = false
if (data.password && data.password.length < 5) {
error = true
console.log('password was too short')
setErrors({...errors, short: 'Password must contain at least 5 characters'})
console.log('short set')
}
if (data.confirmPassword && data.confirmPassword !== data.password) {
error = true
setErrors({...errors, mismatch: "Passwords don't match"})
}
return error
}
const handleSubmit = e => {
e.preventDefault()
console.log(data)
if (validateFields()) {
return
}
}
return (
<Grid id='registration-form' container xs={12} direction='column'>
<Grid item xs={12} align='center'>
<h1>Register</h1>
</Grid>
<form onSubmit={handleSubmit}>
<Grid container spacing={2} xs={12} alignItems='center' justify='center'>
<Grid container item xs={3} direction='column' spacing={2}>
<Grid item>
<TextField id='username' name='username' label='Username' onChange={handleChange} value={data.username} required />
</Grid>
<Grid item>
<TextField id='email' name='email' label='Email' onChange={handleChange} value={data.email} required type='email' />
</Grid>
<Grid item>
<TextField id='password' name='password' label='Password' onChange={handleChange} value={data.password} error={errors.short !== ''} helperText={errors.short} required type='password' />
</Grid>
<Grid item>
<TextField
id='confirm-password'
name='confirmPassword'
label='Confirm Password'
onChange={handleChange}
value={data.confirmPassword}
error={Boolean(errors?.mismatch)}
helperText={errors?.mismatch}
required
type='password'
/>
</Grid>
</Grid>
</Grid>
</form>
<Grid item align='center'>
<a href='#'>Already have an account? Login</a>
</Grid>
</Grid>
)
}
export default Registration
通过以下代码更改您的验证函数。它会起作用。
const validateFields = () => {
let error = false
if (data.password && data.password.length < 5) {
error = true
console.log('password was too short')
//notice updater function here
setErrors(state=>({...state, short: 'Password must contain at least 5 characters'}))
console.log('short set')
}
if (data.confirmPassword && data.confirmPassword !== data.password) {
error = true
setErrors(state=>({...state, mismatch: "Passwords don't match"}))
}
return error
}
当您的状态更新取决于以前的状态值时,传递函数而不是对象来设置状态,以确保调用始终使用状态的最新版本。 传递更新函数允许您访问更新程序内部的当前状态值。