React — Как вернуть ошибки перехвата Axios, встроенные в мою форму?

#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 для ошибок полей, с которыми я работаю.