Node.js 对于无状态React,客户端和客户端的最佳错误处理流程是什么;服务器错误?

Node.js 对于无状态React,客户端和客户端的最佳错误处理流程是什么;服务器错误?,node.js,reactjs,validation,graphql,material-ui,Node.js,Reactjs,Validation,Graphql,Material Ui,我添加了整个组件,因为我是新发布的,所以我认为更多的信息总比不够好。基本上,表单是“无状态的”,而不是使用表单本身所持有的状态。我试图处理来自两个角度的错误。客户端错误,例如, “密码不匹配”,不是有效的电子邮件“,等等。我正在尝试使用验证器库的对象。第二个角度是服务器端错误。目前错误将来自我的突变反应。我希望我能找到一个平滑的方法来处理这些错误而不需要状态,目前我将尝试为客户端使用handleChange函数。如果这是一种不好的方法或数据量大的方法,请分享您的建议/智慧。此外,任何建议或更好的

我添加了整个组件,因为我是新发布的,所以我认为更多的信息总比不够好。基本上,表单是“无状态的”,而不是使用表单本身所持有的状态。我试图处理来自两个角度的错误。客户端错误,例如, “密码不匹配”,不是有效的电子邮件“,等等。我正在尝试使用验证器库的对象。第二个角度是服务器端错误。目前错误将来自我的突变反应。我希望我能找到一个平滑的方法来处理这些错误而不需要状态,目前我将尝试为客户端使用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
//需要访问错误元素,从验证器和服务器更新错误
//并在重新提交或handleChange时重置错误
功能表(道具){
函数句柄更改(事件、值){
const name=event.target.name
console.log(event.target.value)
}
提交时的异步函数(props){
var form=document.querySelector('form')
var values=validate.collectFormValues(表单)
console.log(form.email)
console.log(form.querySelectorAll('p')[0])
试一试{
const results=等待props.client
.变异({
突变:gql`
突变寄存器
($userName:String!,$email:String!,$password:String!){
注册(用户名:$userName,电子邮件:$email,密码:$password){
身份证件
用户名
}
}`,
变量:{
用户名:form.userName.value,
电子邮件:form.email.value,
密码:form.password.value,
}
})
console.log(结果)
}
捕捉(错误){
console.log(错误)
}
}
常量类=useStyles()
返回(
{
手变(活动)
}}/>
未来电子邮件错误
{
手变(活动)
}}/>
{
手变(活动)
}}/>
{
手变(活动)
}}/>
{
提交(道具)
}}>
登记
)
}
导出默认表单

我现在已经把一切都准备好了,到目前为止一切都很好。我在下面发布了我的解决方案,供任何对评论感兴趣的人参考,或者它可能有助于解决您自己的问题

内部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 = ''
    })
  }

这个问题可能有点过于宽泛/固执己见。不过,您可以看看一些更流行的库,如
formik
react-hook-form
,它们使表单验证更容易。我一定会看一看,感谢您的见解。