1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| import { useCallback, useState } from "react"
interface FormState { [key: string]: string }
interface Validatetor { [key: string]: (value: string) => String | null }
interface Errors { [key: string]: String | null }
export const useForm = (initialState: FormState, validatetor: Validatetor) => { const [values, setValues] = useState(initialState) const [erros, setErros] = useState<Errors>({})
const setFileValues = useCallback((name: string, value: string)=>{ setValues((values) => ( { ...values, [name]: value } ))
setErros(erros => ({ ...erros, [name]: validatetor[name](value) }))
}, [])
return { values, erros, setFileValues } }
export const MyForm = () => { const validators = useMemo(() => { return { name: (value: string) => { if (value.length < 2) return "Name length should be no less than 2."; return null; }, email: (value: string) => { if (!value.includes("@")) return "Invalid email address"; return null; }, }; }, []);
const { values, erros, setFileValues } = useForm({}, validators)
const handleSubmit = (e: FormEvent) => { e.preventDefault() console.log(values) }
return ( <form onSubmit={e => handleSubmit(e)}> <div> <label htmlFor="用户名"></label> <input type="text" value={values.name || ''} onChange={(e) => { setFileValues('name', e.target.value) }} /> { erros.name && <div style={{color: 'red'}}> {erros.name} </div> } </div> <div> <label htmlFor="昵称"></label> <input type="text" value={values.email || ''} onChange={(e) => { setFileValues('email', e.target.value) }} /> { erros.email && <div style={{color: 'red'}}> {erros.email} </div> } </div> <button type="submit">提交</button> </form> ) }
|