#javascript #reactjs #material-ui #react-hook-form
#javascript #reactjs #материал-пользовательский интерфейс #react-hook-form
Вопрос:
Во время регистрации пользователя мой серверный сервер информирует клиента, если адрес электронной почты и / или имя пользователя в настоящее время используются кем-то другим. Ниже приведен ответ, зарегистрированный в webconsole благодаря ошибке перехвата Axios.
Я хотел бы сопоставить каждый email
и username
с соответствующим полем. Моя форма основана на Material-UI и react-hook-form
Вот пример ответа об ошибке, предоставленного моим экземпляром Axios.
{
"email":["This email is already in use"],
"username":["This username is already in use"]
}
Вот моя полная форма react, я вырезал некоторые вещи, чтобы ее было легче читать:
export default function SignUp()
{
const { register, control, errors: fieldsErrors, handleSubmit } = useForm()
const onSubmit = (data, e) => {
console.log(data);
axiosInstance
.post(`api/user/register/`, {
email: data.email,
username: data.username,
password: data.password,
})
.then((res) => {
history.push('/login');
console.log(res);
console.log(res.data);
})
.catch(err => {
console.error(err.response.data);
}
)
};
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}></Avatar>
<Typography component="h1" variant="h5">
Sign up
</Typography>
<form className={classes.form} noValidate onSubmit={handleSubmit(onSubmit)}>
<FormControl fullWidth variant="outlined">
<Grid container spacing={2}>
<Grid item xs={12}>
<Controller
name="email"
as={
<TextField
variant="outlined"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
error={Boolean(fieldsErrors.email)}
onChange={
(evt) =>
{
let key = evt.currentTarget.name;
let value = evt.currentTarget.value;
handleChange({ [key]: value });
}
}
/>
}
control={control}
defaultValue=""
rules={{
required: 'Required',
pattern: {
value: /^[A-Z0-9._% -] @[A-Z0-9.-] .[A-Z]{2,4}$/i,
message: 'invalid email address'
}
}}
/>
</Grid>
<Grid item xs={12}>
<Controller
name="username"
as={
<TextField
variant="outlined"
required
fullWidth
id="username"
label="Username"
name="username"
onChange={
(evt) => {
let key = evt.currentTarget.name;
let value = evt.currentTarget.value;
handleChange({[key]: value});
}
}
/>
}
control={control}
defaultValue=""
rules={{
required: 'Required',
pattern: {
value: /^(?!.*..)(?!.*.$)[^W][w.]{0,29}$/i,
message: 'Invalid use of characters'
}
}}
/>
{fieldsErrors.username?.type amp;amp; <p>{fieldsErrors.username?.message}</p>}
</Grid>
<Grid item xs={12}>
<Controller
name="password"
as={
<TextField
variant="outlined"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={
(evt) =>
{
let key = evt.currentTarget.name;
let value = evt.currentTarget.value;
handleChange({ [key]: value });
}
}
/>
}
control={control}
defaultValue=""
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={handleSubmit}
>
Sign Up
</Button>
</FormControl>
</form>
</div>
</Container>
);
}
Мне удалось создать ошибку в webalert, но это выглядело не очень хорошо. Есть ли какой-нибудь простой способ реализовать мою ошибку перехвата в моей форме?
Я использую это поле ошибка :
{fieldsErrors.username?.type amp;amp; <p>{fieldsErrors.username?.message}</p>}
Как моя ошибка регулярного выражения, чтобы предупредить пользователей о недопустимых символах в их имени пользователя. Я подумал, может быть, я мог бы добавить туда ошибки? Но я не знаю, как это сделать.
Ответ №1:
Вы можете использовать useState
перехват для хранения ошибок из API. Затем вы можете использовать свой шаблон для отображения этих ошибок в том же формате, в котором отображаются ошибки регулярных выражений.
Кстати, в целях безопасности не стоит сообщать пользователю, что электронное письмо уже принято. Но если в вашем приложении нет конфиденциальных данных, это не имеет большого значения.
РЕДАКТИРОВАТЬ: пример
export default function SignUp()
{
const [ apiError, setApiError ] = useState(null)
const onSubmit = (data, e) => {
setApiError(null)
axiosInstance
//...
.catch(err => {
setApiError(err.response.data.message)
console.error(err.response.data);
}
)
};
return (
//....
{apiError amp;amp; <p>{apiError}</p>}
//....
)
Комментарии:
1. Ах, я вижу риски для безопасности, позволяя пользователям знать, что электронное письмо принято. Спасибо, что заставили меня дважды подумать об этом. Есть ли у вас какой-либо псевдокод, который поможет мне использовать useState с моими ошибками Axios?
2. Привет, jlogan, извините за беспокойство. Я внедрял ваш код, следуя вашим указаниям. Я не получаю никаких синтаксических ошибок, но при использовании не отображается предупреждающее сообщение переднего
{apiError amp;amp; <p>{apiError}</p>}
плана? У вас есть какие-либо идеи, почему это может быть так?3. Вы уверены, что передаете сообщение об ошибке
setApiError
? Я использовалerr.response.data.message
в качестве примера. Я не знаю, какой будет структура ваших данных об ошибках.4. О, хорошо, я понимаю, как. Должен ли я создавать два разных состояния для каждой ошибки? В моем оригинальном сообщении я показал ответ JSON. Вот как я могу заставить его работать сейчас :
setApiError(err.response.data.email)
. Я думаю, у меня было бы два состояния make two для ошибок полей, с которыми я работаю.