lesson 2, chapter 1 /ru

This commit is contained in:
2023-07-01 16:33:57 +02:00
parent 19c3d1b636
commit dc188f5ae1
10 changed files with 783 additions and 626 deletions

View File

@@ -6,5 +6,6 @@
"href": "https://www.figma.com/file/PwHkQjA62wyw8BSEyW4gIk/%D0%9E%D0%B1%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D1%87%D0%BA%D0%B0%D0%BC?node-id=0%3A1&mode=dev", "href": "https://www.figma.com/file/PwHkQjA62wyw8BSEyW4gIk/%D0%9E%D0%B1%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D1%87%D0%BA%D0%B0%D0%BC?node-id=0%3A1&mode=dev",
"newWindow": true "newWindow": true
}, },
"lesson-1": "Lesson 1: Hello World!" "lesson-1": "Lesson 1: Hello World!",
"lesson-2": "Lesson 2: Forms"
} }

View File

@@ -6,5 +6,6 @@
"href": "https://www.figma.com/file/PwHkQjA62wyw8BSEyW4gIk/%D0%9E%D0%B1%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D1%87%D0%BA%D0%B0%D0%BC?node-id=0%3A1&mode=dev", "href": "https://www.figma.com/file/PwHkQjA62wyw8BSEyW4gIk/%D0%9E%D0%B1%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D1%87%D0%BA%D0%B0%D0%BC?node-id=0%3A1&mode=dev",
"newWindow": true "newWindow": true
}, },
"lesson-1": "Урок 1" "lesson-1": "Урок 1",
"lesson-2": "Урок 2: Формы"
} }

View File

@@ -0,0 +1,7 @@
{
"chapter-1": "Chapter 1",
"chapter-2": "Chapter 2",
"chapter-3": "Chapter 3",
"chapter-4": "Chapter 4",
"chapter-5": "Chapter 5"
}

View File

@@ -0,0 +1,7 @@
{
"chapter-1": "Chapter 1",
"chapter-2": "Chapter 2",
"chapter-3": "Chapter 3",
"chapter-4": "Chapter 4",
"chapter-5": "Chapter 5"
}

View File

@@ -0,0 +1 @@
# Under construction

View File

@@ -0,0 +1,128 @@
# Формы
## React-hook-form
[React-hook-form](https://react-hook-form.com/) - это библиотека для управляемых форм в React. Она позволяет управлять состоянием формы и валидацией внутри формы. В отличие от других библиотек, таких как Formik, React-hook-form не использует контекст, а вместо этого полагается на нативные возможности React, такие как управляемые компоненты и хуки.
### Установка
```bash
pnpm i react-hook-form
```
### Использование
```tsx filename="src/components/auth/login-form/login-form.tsx"
import { useForm } from 'react-hook-form'
import { Button } from '../../ui/button'
import { TextField } from '../../ui/text-field'
type FormValues = {
login: string
password: string
}
export const LoginForm = () => {
const { register, handleSubmit } = useForm<FormValues>()
const onSubmit = (data: FormValues) => {
console.log(data)
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<TextField {...register('login')} label={'login'} />
<TextField {...register('password')} label={'password'} />
<Button type="submit">Submit</Button>
</form>
)
}
```
```tsx filename="src/components/auth/login-form/login-form.stories.tsx"
import type { Meta, StoryObj } from '@storybook/react'
import { LoginForm } from './login-form'
const meta = {
title: 'Auth/LoginForm',
component: LoginForm,
tags: ['autodocs'],
} satisfies Meta<typeof LoginForm>
export default meta
type Story = StoryObj<typeof meta>
export const Primary: Story = {}
```
Проверим:
![login-form-minimal.png](./images/login-form-minimal.png)
Все работает как надо на данном этапе, но не хватает чекбокса rememberMe. Добавим его:
```tsx filename="login-form.tsx" showLineNumbers {4,11}
type FormValues = {
login: string
password: string
rememberMe: boolean
}
...
return (
<form onSubmit={handleSubmit(onSubmit)}>
<TextField {...register('login')} label={'login'} />
<TextField {...register('password')} label={'password'} />
<Checkbox {...register('rememberMe')} label={'remember me'} />
<Button type="submit">Submit</Button>
</form>
)
...
```
Проверяем и получаем вот такой результат:
![login-form-checkbox-error.png](./images/login-form-checkbox-error.png)
Совсем нет то что мы ожидали. Это происходит из-за того что чекбокс из radix ui не совместим напрямую с register().
Что бы это исправить, воспользуемся хуком useController из react-hook-form:
```tsx filename="login-form.tsx" showLineNumbers {1,14,20-26,32}
import { useController, useForm } from 'react-hook-form'
import { Checkbox } from '../../ui/checkbox'
import { TextField } from '../../ui/text-field'
import { Button } from '../../ui/button'
type FormValues = {
login: string
password: string
rememberMe: boolean
}
export const LoginForm = () => {
const { control, handleSubmit, register } = useForm<FormValues>()
const onSubmit = (data: FormValues) => {
console.log(data)
}
const {
field: { value, onChange },
} = useController({
name: 'rememberMe',
control,
defaultValue: false,
})
return (
<form onSubmit={handleSubmit(onSubmit)}>
<TextField {...register('login')} label={'login'} />
<TextField {...register('password')} label={'password'} />
<Checkbox onCheckedChange={onChange} checked={value} label={'remember me'} />
<Button type="submit">Submit</Button>
</form>
)
}
```
Теперь все должно работать как надо!

View File

@@ -0,0 +1 @@
# Under construction

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

1259
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff