Итак, я работаю над проектом, который включает отправку данных формы в базу данных. Пока я просто использую Mock API, чтобы все настроить и запустить перед настройкой базы данных в .NET.
Я использую пользовательский хук с двумя основными функциями: handleChangeEvent(), который отвечает за установку новых значений в основном компоненте, CreateUser, и handleSubmit(), который вызывает мой пользовательский валидатор (validateNewUser) для проверки ошибок в форма.
Мой хук и валидатор работают нормально, но у меня проблемы с почтовым запросом Axios. Я могу поместить свой почтовый запрос Axios в свой пользовательский хук, и он работает по назначению, но я не могу понять, как отправить форму в Mock API, только когда форма правильно заполнена.
Я попытался использовать оператор if в моей функции handlePost (что, как мне кажется, является правильным способом сделать это, я мог просто что-то упустить, я мог ошибаться), я попытался поместить запрос Axios внутри функции handlePost, но это дало Нет прогресса.
То, как я его установил, в настоящее время работает, но в основном каждый раз, когда вы нажимаете «Отправить», он отправляет данные в API, скорее всего, потому, что он каждый раз отправляет форму. Другой способ, которым я мог бы это сделать, - это настроить всплывающие сообщения об ошибках, когда пользователь заполняет форму? Чтобы форма была точной еще до ее отправки.
Я новичок в React, поэтому прошу прощения, если мой вопрос/проблема сбивает с толку. Если нужна дополнительная информация, я предоставлю все, что смогу.
Код для всех задействованных частей будет ниже, и мы будем очень признательны за любой ввод.
использоватьCreateUser.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 handleChangeEvent = 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.info(response.data);
})
}
}
return {handleChangeEvent, 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;
}
CreateUser.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 {handleChangeEvent, 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 = {handleChangeEvent} />
{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 = {handleChangeEvent} />
{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 = {handleChangeEvent} />
{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 = {handleChangeEvent} />
{errors.password && <p style = {{color: "red"}}>{errors.password}</p>}
</Form.Field>
<Button type='submit'}>Submit</Button>
</Form>
</Box>
)
}
export default CreateUser;
🤔 А знаете ли вы, что...
С React можно создавать одностраничные приложения (SPA), не перезагружая страницу.
Несколько указателей Лучше давать обратную связь пользователю по мере того, как он вводит данные
// validate on change
const handleChangeEvent = 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.info(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, проверки.
Размышление о состояниях компонентов также поможет вам проектировать более качественные компоненты.
Надеюсь, это поможет в некотором роде,
Ваше здоровье