【问题标题】:ReactJS Handling Form Errors With MaterialUIReactJS 使用 MaterialUI 处理表单错误
【发布时间】:2021-03-23 21:29:47
【问题描述】:

提交表单后,我想验证两个字段。具体来说,我想检查密码是否至少包含 5 个字符,以及密码和确认密码字段是否匹配。我继续执行状态来保存这些错误消息。但是,并非所有错误都显示出来。示例:假设用户在密码字段中输入了“hell”,而对于密码确认,他们输入了“hello”。您会看到 2 条错误消息(密码太短,密码不匹配),但我的表单只显示一个错误 - 密码不匹配。

我怀疑问题出在 validateFields 函数中。如果我交换 if 语句的顺序并输入我上面描述的相同输入,那么我设法看到“密码必须包含至少 5 个字符”错误,但没有看到“密码不匹配错误”。此外,在使用 react dev-tools 时,我注意到在错误状态下只设置了一条消息。所以我认为我没有正确使用 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

【问题讨论】:

    标签: javascript reactjs material-ui react-state


    【解决方案1】:

    通过以下代码更改您的验证功能。它会起作用的。

    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
    }
    

    当您的状态更新依赖于之前的状态值时,请传递一个函数而不是一个对象来设置状态,以确保调用始终使用最新版本的状态。 传递更新函数允许您访问更新程序中的当前状态值。

    【讨论】:

    • 是的,它有效!但是,为什么一个函数可以确保您可以访问最新版本的状态?状态是一个全局对象,所以我想直接访问它会包含最新的状态。
    • 由于 setState 是一个异步调用,因此您不能依赖当前状态值是否更新。在这里,如果两个 if 条件都为真,那么状态值可能是更新的,也可能不是更新的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多