/
lizardking
/
react_project
Обзор
Документация
Войти
/
lizardking
/
react_project
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/features/react19/ActionStateWithReducer/model/useActionForm.ts
76 строк
2 KB
LizardKing
Task 9 - React 19
14 ноя 2025, 20:35
14 ноя 2025, 20:35
86e4531
Код
Авторство
О чём код?
import { useActionState, useEffect, useRef } from 'react' import { simulateDelay } from '../../lib/simulateDelay' import { initialActionFormState, type ActionFormState, type ActionFormStatus, } from './formState' type ActionFormViewStatus = ActionFormStatus | 'submitting' export function useActionForm() { const formRef = useRef<HTMLFormElement | null>(null) const [state, formAction, isPending] = useActionState<ActionFormState, FormData>( async (previousState, formData) => { const rawName = formData.get('name') const rawEmail = formData.get('email') const rawMessage = formData.get('message') const name = typeof rawName === 'string' ? rawName.trim() : '' const email = typeof rawEmail === 'string' ? rawEmail.trim() : '' const message = typeof rawMessage === 'string' ? rawMessage.trim() : '' if (!name || !email || !message) { return { ...previousState, status: 'error', errorMessage: 'Все поля обязательны для заполнения', } } await simulateDelay(1000) return { status: 'success', errorMessage: null, } }, initialActionFormState, ) useEffect(() => { if (state.status !== 'success') { return } if (formRef.current) { formRef.current.reset() } }, [state.status]) const viewStatus: ActionFormViewStatus = isPending ? 'submitting' : state.status const isDirty = viewStatus === 'submitting' || viewStatus === 'error' const statusLabel = (() => { if (viewStatus === 'submitting') { return 'Отправляем…' } if (viewStatus === 'success') { return 'Сохранено!' } if (viewStatus === 'error') { return state.errorMessage ?? 'Ошибка при сохранении' } return null })() return { formRef, status: viewStatus, isDirty, isPending, statusLabel, formAction, } }