45 lines
895 B
TypeScript
45 lines
895 B
TypeScript
|
|
import { useCallback, useRef, useState } from 'preact/hooks'
|
||
|
|
|
||
|
|
type Props<TValue> = {
|
||
|
|
onSubmit: (value: TValue) => void
|
||
|
|
defaultValue: TValue | (() => TValue)
|
||
|
|
}
|
||
|
|
|
||
|
|
export const useForm = <TValue = unknown>({
|
||
|
|
defaultValue,
|
||
|
|
onSubmit,
|
||
|
|
}: Props<TValue>) => {
|
||
|
|
const [formState, setFormState] = useState(defaultValue)
|
||
|
|
|
||
|
|
const submitRef = useRef(onSubmit)
|
||
|
|
const stateRef = useRef(formState)
|
||
|
|
|
||
|
|
submitRef.current = onSubmit
|
||
|
|
stateRef.current = formState
|
||
|
|
|
||
|
|
const handleChange = useCallback((e: Event) => {
|
||
|
|
const target = e.target as HTMLSelectElement | HTMLInputElement
|
||
|
|
|
||
|
|
setFormState(
|
||
|
|
(previous) =>
|
||
|
|
({
|
||
|
|
...previous,
|
||
|
|
[target.name]: target.value,
|
||
|
|
} as TValue)
|
||
|
|
)
|
||
|
|
}, [])
|
||
|
|
|
||
|
|
const handleSubmit = useCallback((e: Event) => {
|
||
|
|
e.preventDefault()
|
||
|
|
e.stopPropagation()
|
||
|
|
|
||
|
|
submitRef.current(stateRef.current)
|
||
|
|
}, [])
|
||
|
|
|
||
|
|
return {
|
||
|
|
value: formState,
|
||
|
|
handleChange,
|
||
|
|
handleSubmit,
|
||
|
|
}
|
||
|
|
}
|