/
lizardking
/
react_final
Обзор
Документация
Войти
/
lizardking
/
react_final
Код
Запросы
1
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
old
src/widgets/SignUpForm/ui/SignUpForm.tsx
140 строк
6 KB
LizardKing
Initial commit
22 ноя 2025, 15:56
22 ноя 2025, 15:56
0df0d9e
Код
Авторство
О чём код?
import { yupResolver } from '@hookform/resolvers/yup' import LockOutlinedIcon from '@mui/icons-material/LockOutlined' import LoadingButton from '@mui/lab/LoadingButton' import { Avatar, Box, Container, Link, TextField, Typography } from '@mui/material' import type { FC } from 'react' import type { SubmitHandler } from 'react-hook-form' import { Controller, useForm } from 'react-hook-form' import { Link as RouterLink, useNavigate } from 'react-router-dom' import { toast } from 'react-toastify' import { useSignUpMutation } from 'shared/store/api/authApi' import { userActions } from 'shared/store/slices/user' import { useAppDispatch } from 'shared/store/utils' import { getMessageFromError } from 'shared/utils' import type { SignUpFormValues } from '../utils/types' import { signUpFormSchema } from '../utils/validator' export const SignUpForm: FC = () => { const dispatch = useAppDispatch() // navigate поможет сделать редирект в нужный момент const navigate = useNavigate() // Из хука useSignUpMutation (был получен путем автогенерации) // достаем функцию, которая будет (регистрировать пользователя) делать POST-запрос к нашем серверу) const [signUpRequestFn] = useSignUpMutation() // инициализируем react-hook-form const { // control понадобиться, чтобы подружить react-hook-form и компоненты из MUI control, handleSubmit, formState: { errors, isValid, isSubmitting, isSubmitted }, // с помощью generic подсказываем react-hook-form, какие поля содержит наша форма } = useForm<SignUpFormValues>({ defaultValues: { email: '', password: '', }, // react-hook-form умеет работать со многими библиотеками // валидации, мы используем yup resolver: yupResolver(signUpFormSchema), }) const submitHandler: SubmitHandler<SignUpFormValues> = async (values) => { try { // метод "unwrap" помогает убрать вспомогательные обертки // RTK, которые обрабатывают ошибки. Теперь ошибки обрабатываем мы // с помощью конструкции try...catch. В этом случае нам так удобней const response = await signUpRequestFn(values).unwrap() dispatch(userActions.setUser(response.user)) dispatch(userActions.setAccessToken({ accessToken: response.accessToken })) // Выводим уведомление, что пользователь успешно зарегался // Есть куча библиотек для отображения "Тостеров". Мы используем // react-toastify — https://github.com/fkhadra/react-toastify#readme toast.success('Вы успешно зарегистрированы!') await navigate('/') } catch (error) { // Если произошла ошибка, то выводим уведомление // eslint-disable-next-line console.log({ error }) toast.error(getMessageFromError(error, 'Не известная ошибка при регистрации пользователя')) } } return ( <Container component="main" maxWidth="xs"> <Box sx={{ marginTop: 8, display: 'flex', flexDirection: 'column', alignItems: 'center', }} > <Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}> <LockOutlinedIcon /> </Avatar> <Typography component="h1" variant="h5"> Sign Up </Typography> <Box component="form" onSubmit={handleSubmit(submitHandler)} noValidate sx={{ mt: 1 }}> {/* Чтобы подружить react-hook-form с MUI используем компонент Controller смотри доку https://react-hook-form.com/get-started#IntegratingwithUIlibraries */} <Controller name="email" control={control} render={({ field }) => ( <TextField margin="normal" label="Email Address" type="email" fullWidth required autoComplete="email" error={!!errors.email?.message} helperText={errors.email?.message} {...field} /> )} /> <Controller name="password" control={control} render={({ field }) => ( <TextField label="Password" type="password" error={!!errors.password?.message} helperText={errors.password?.message} margin="normal" fullWidth required {...field} /> )} /> <LoadingButton type="submit" // кнопка становится недоступной после первой валидации (если есть ошибки) // или когда выполняется отправка (чтобы не дать пользователю отправить форму несколько раз) disabled={isSubmitted && (!isValid || isSubmitting)} loading={isSubmitting} fullWidth variant="contained" sx={{ mt: 3, mb: 2 }} > Sign Up </LoadingButton> <Box display="flex" justifyContent="center" flexGrow={1}> <Link component={RouterLink} to="/signin"> SIGN IN </Link> </Box> </Box> </Box> </Container> ) }