node.js - 对于无状态 React 表单(客户端和服务器错误)的最佳错误处理流程是什么?
问题描述
我添加了整个组件,因为我是新手,所以我认为更多信息总比不够好。基本上它所在的表格是“无状态的”,除了使用表格本身持有的状态。我正在尝试处理来自两个角度的错误。客户端错误,例如“密码不匹配”、“不是有效的电子邮件”等。我正在尝试使用验证器库。第二个角度是服务器端错误。目前错误将来自我的突变响应。我我希望我能找到一种在没有状态的情况下处理这些错误的平滑方法,目前我将尝试为客户端使用 handleChange 函数。如果这是一种不好的方法或数据量很大,请分享您的建议/智慧。此外,任何建议或代码中非常感谢更好的实践,并在以后的发布中。谢谢(对全栈开发非常陌生)
进口
import React from 'react'
import Container from '@material-ui/core/Container'
import { makeStyles } from '@material-ui/core/styles'
import TextField from '@material-ui/core/TextField'
import Button from '@material-ui/core/Button'
import Paper from '@material-ui/core/Paper'
import gql from 'graphql-tag'
import { useMutation } from '@apollo/react-hooks'
import FormHelperText from '@material-ui/core/FormHelperText'
import validate from 'validate.js'
import FormControl from '@material-ui/core/FormControl'
用于样式的材质 UI
const useStyles = makeStyles({
form: {
width: '100%',
marginTop: 15,
},
paper: {
marginTop: 15,
},
register: {
margin: 15,
color: 'white',
backgroundColor: '#414849',
width: '95%'
},
email: {
margin: 15,
width: '95%'
},
username: {
margin: 15,
width: '95%'
},
password: {
margin: 15,
width: '95%'
},
confirmPassword : {
margin: 15,
width: '95%'
}
})
表单组件
// need to access error elements, update errors from validator & from server
// and also reset errors either on resubmit, or handleChange
function Form (props){
function handleChange(event, value){
const name = event.target.name
console.log(event.target.value)
}
async function onSubmit(props){
var form = document.querySelector('form')
var values = validate.collectFormValues(form)
console.log(form.email)
console.log(form.querySelectorAll('p')[0])
try{
const results = await props.client
.mutate({
mutation: gql`
mutation register
($userName: String!, $email: String!, $password: String!){
register(userName: $userName, email: $email, password: $password){
id
userName
}
}`,
variables: {
userName: form.userName.value,
email: form.email.value,
password: form.password.value,
}
})
console.log(results)
}
catch (err) {
console.log(err)
}
}
const classes = useStyles()
return(
<Container component="main" maxWidth="sm">
<Paper className={classes.paper}>
<form
name='form'
className={classes.form}>
<TextField
className={classes.email}
name='email'
variant='outlined'
type='text'
label='Email'
InputLabelProps={{
shrink: true,
}}
onChange={(event) => {
handleChange(event)
}}/>
<FormHelperText
name='emailError'
>
Future Email Error
</FormHelperText>
<TextField
className={classes.username}
name='userName'
variant='outlined'
type='text'
label='Username'
InputLabelProps={{
shrink: true,
}}
onChange={(event) => {
handleChange(event)
}}/>
<TextField
className={classes.password}
name='password'
variant='outlined'
type='text'
label='Password'
InputLabelProps={{
shrink: true,
}}
onChange={(event) => {
handleChange(event)
}}/>
<TextField
className={classes.confirmPassword}
name='confirmPassword'
variant='outlined'
type='text'
label='Confirm Password'
InputLabelProps={{
shrink: true,
}}
onChange={(event) => {
handleChange(event)
}}/>
<Button
className={classes.register}
variant='contained'
onClick={()=> {
onSubmit(props)
}}>
REGISTER
</Button>
</form>
</Paper>
</Container>
)
}
export default Form
解决方案
我现在把它全部连接起来了,到目前为止一切都很好。我在下面为任何对批评感兴趣的人发布了我的解决方案,或者它可能有助于解决您自己的问题。
在 onSubmit 函数中。
var clientError;
var form = document.querySelector('form')
var values = validate.collectFormValues(form)
var errors = await validate(values, constraints)
if(errors == undefined){
clientError = false
} else clientError = true
resetErrors(form)
handleErrors(form, errors || {})
if(clientError == false){
try{
const results = await props.client
.mutate({
mutation: gql`
mutation register
($userName: String!, $email: String!, $password: String!){
register(userName: $userName, email: $email, password: $password){
id
userName
}
}`,
variables: {
userName: form.userName.value,
email: form.email.value,
password: form.password.value,
}
})
console.log(results)
props.props.history.push('/login')
}
catch (err) {
handleGraphqlErrors(form, err)
}
}
}
错误处理的实际功能
//handle return errors from mutation
function handleGraphqlErrors(form, err){
const graphqlErrors = err.toString().slice(22)
console.log(graphqlErrors)
if(graphqlErrors == 'Username is already taken'){
document.getElementById('userNameError').innerHTML = graphqlErrors
}
if(graphqlErrors == 'Email is already in use'){
document.getElementById('emailError').innerHTML = graphqlErrors
}
}
//map errors to proper input fields
function handleErrors(form, errors){
Object.keys(errors).map((key, index) => {
console.log(errors[key])
document.getElementById(`${key}Error`).innerHTML = errors[key]
})
}
//reset error input fields to blank
function resetErrors(form){
var errorInputs = form.querySelectorAll('p')
Object.keys(errorInputs).map(key => {
errorInputs[key].innerHTML = ''
})
}
推荐阅读
- python - Python矩阵乘法
- node.js - 我想使用 javascript for 循环从给定的 json 值中自定义 json 格式
- r - ggplot - 我可以绘制每个方面的所有数据,同时分割另一个变量吗?
- spring-boot - Spring Bean 中的自动装配枚举
- javascript - 在我的 React 应用程序中使用 redux dispatch 获取 TypeScript 错误
- java - 无限循环的线程是否会导致 CPU 过多
- perl - 在 Perl 中将 Unicode 数学粗体/斜体字符转换为 latin-1
- android - 如何在Android中开发具有相同packageName的应用程序的广告和广告免费版本(免费+付费)?
- javascript - 将数据分成块并在谷歌应用脚本中对每个块执行单独的函数执行
- amazon-web-services - 如何在 Elastic Beanstalk 上设置从 http 到 https 的重定向