reactjs 如何使用Axios仅在表单填写正确时提交表单数据

f45qwnt8  于 2022-11-29  发布在  React
关注(0)|答案(1)|浏览(143)

背景信息:

因此,我正在进行一个项目,其中包括将表单数据发送到数据库。目前,我只是在. NET中设置数据库之前使用Mock API来启动和运行所有内容。

自定义挂钩和验证器信息:

我使用的是一个自定义钩子,它有两个主要功能:**handleChange()**负责在主组件CreateUser上设置新值,**handleSubmit()**调用我的自定义验证器(validateNewUser)检查表单中的错误。
我的钩子和验证器工作正常,但Axios post请求有问题。我可以将Axios post请求放在我的自定义钩子中,它按预期工作,但我不知道如何仅在正确填写表单时才将表单发送到Mock API。

到目前为止的试验和错误:

我曾尝试在handlePost函数中使用if语句(我认为这是正确的方法,我可能只是遗漏了一些东西,我可能是错的),我尝试将Axios请求放在handlePost函数中,但没有取得任何进展。
我目前设置的方式是有效的,但基本上只要您单击提交,它就会将数据发送到API,很可能是因为它每次都提交表单。另一种方法可能是设置用户填写表单时弹出错误,以便表单在提交之前就准确无误。
我是React的新手,如果我的问题令人困惑,我向你道歉。如果需要更多信息,我会尽我所能提供。
所有涉及的部分的代码将在下面,任何和所有的输入是非常感谢。

主代码:

使用创建用户.jsx:

import { useState } from 'react';
import axios from 'axios';

const useCreateUser = (validateNewUser) => {
    const [values, setValues] = useState({
        firstName: '',
        lastName: '',
        email: '',
        password: ''
    });

    const [errors, setErrors] = useState({});

    const handleChange = e => {
        const {name, value} = e.target
        setValues({
            ...values,
            [name]: value
        });
    };

    const handleSubmit = e => {
    e.preventDefault();
    setErrors(validateNewUser(values));

    const user = {
        firstName: values.firstName,
        lastName: values.lastName,
        email: values.email,
        password: values.password
        };

    if (handleSubmit){
        axios.post(url, user)
        .then((response) => {
        console.log(response.data);
    })
    }
}

  return {handleChange, values, handleSubmit, errors}
}

export default useCreateUser;

验证新用户.jsx:

export default function validateNewUser(values) {
    let errors = {}

    //Validate First Name
    if(!values.firstName.trim()) {
        errors.firstName = 'First Name is Required.'
    }

    //Validate Last Name
    if(!values.lastName.trim()) {
        errors.lastName = 'Last Name is Required.'
    }

    //Validate Email
    if(!values.email){
        errors.email = 'Email is Required.'
    } else if(!/\S+@\S+\.\S+/.test(values.email)) {
        errors.email = 'Invalid Email Address.'
    }

    if(!values.password){
        errors.password = 'Password is Required.'
    } else if(values.password.length < 6) {
        errors.password = 'Password must be greater than 6 characters.'
    }

    return errors;

}

创建用户.jsx:

import Header from "../Header";
import { Form, Button } from "semantic-ui-react";
import { Box } from "@mui/material";
import useCreateUser from "../../hooks/useCreateUser";
import validateNewUser from "../../validators/validateNewUser";

const CreateUser = () => {
    const {handleChange, values, handleSubmit, errors} = useCreateUser(validateNewUser);
    
    return (
    <Box m="20px">
        <Box 
        display="flex" 
        justifyContent="space-between" 
        alignItems="center"
        margin="0 auto"
        marginBottom="20px"
        >
            <Header title="Create a New User" subtitle="Please ensure to select the correct role."/>
        </Box>

        <Form onSubmit={handleSubmit}>
            <Form.Field>
                <label>First Name</label>
                <input placeholder='First Name' name='firstName' type='text' value={values.firstName} onChange={handleChange} />
                {errors.firstName && <p style={{color: "red"}}>{errors.firstName}</p>}
            </Form.Field>
            <Form.Field>
                <label>Last Name</label>
                <input placeholder='Last Name' name='lastName' type='text' value={values.lastName}  onChange={handleChange} />
                {errors.lastName && <p style={{color: "red"}}>{errors.lastName}</p>}
            </Form.Field>
            <Form.Field>
                <label>Email</label>
                <input placeholder='Email' name='email' type='email' value={values.email} onChange={handleChange} />
                {errors.email && <p style={{color: "red"}}>{errors.email}</p>}
            </Form.Field>
            <Form.Field>
                <label>Password</label>
                <input placeholder='Password' name='password' type='password' value={values.password} onChange={handleChange} />
                {errors.password && <p style={{color: "red"}}>{errors.password}</p>}
            </Form.Field>
            <Button type='submit'}>Submit</Button>
        </Form>
    </Box>
    )

}

export default CreateUser;
z2acfund

z2acfund1#

在用户输入数据时,最好向用户给予反馈

// validate on change
const handleChange = e => {

    const { name, value } = e.target;

    const updatedValues = { ...values, [name]: value };

    setValues(updatedValues)

    const validationErrors = validateNewUser(updatedValues);

    setErrors(validationErrors)

};

在“提交”时,可以返回第一个错误,以便窗体可以滚动或聚焦到出现错误的字段。

const handleSubmit = async (e) => {

    e.preventDefault();
  
    // this might  not be needed
    // you can do validations which need api calls
    // but event those can be done on input
    // setErrors(validateNewUser(values));

    // return error code
    const firstErrorKey = Object.keys(error)[0]
    if (firstErrorKey !== undefined) {
       return { hasError: true } 
    }

    const user = {
        firstName: values.firstName,
        lastName: values.lastName,
        email: values.email,
        password: values.password
    };

    const response = await axios.post(url, user)
    console.log(response.data);

    // return success code depending on server response
    // so u can show success
    // return { isSuccess: response.data?.code === 0 } 

    }
}

在窗体中可以设置加载程序设置加载程序

const onFormSubmit = async e => {
   try {

      setState('submitting')

      const response = await handleSubmit(e);

      if (response.isSuccess) {
        // show alert/toast
      }

     if (response.hasErrors) {
       // focus on first error control
        const firstErrorKey = Object.keys(error)[0]
        if (firstErrorKey !== undefined) {
           // focus on control with error
        }
     }

      setState('success')

   } catch(error) {
     setState('error')
   }
 }

 <Form onSubmit={handleSubmit}>

 </Form>

如果你能把表单输入状态从api逻辑中分离出来,这将使代码更容易维护。
如果可能的话,使用像Formik这样的库,它们处理表单状态,并允许您专注于代码的业务部分,如api调用、验证
考虑组件状态还有助于设计更好的组件
希望能有所帮助,
干杯

相关问题