import { useRef, type InputHTMLAttributes } from "react"; type defaultValues = Record; interface Props { initialValues?: Partial; } type InputElements = | HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement ; interface UseFormReturns { getValue: () => T; setValue: (name: keyof T, value: string | number) => void; setValues: (values: Partial) => void; bindInput: (name: keyof T) => InputHTMLAttributes; // onSubmit: (values: T) => (ev: React.FormEvent) => void onSubmit: (fn: (values: T) => void) => (ev: React.FormEvent) => void } function useForm({ initialValues }: Props) { const inputs = useRef>>({}); const values = useRef({ ...initialValues } as T); const inst = useRef>(); if (!inst.current) { const getValue = () => { return values.current; } const setValue = (name, value) => { console.log(inputs.current[name], name); if (inputs.current[name]) { values.current[name as keyof T] = value; inputs.current[name].value = value; } } const setValues = (values) => { Object.keys(values).forEach((key) => { setValue(key, values[key]); }); } const bindInput = (name: string) => { console.log('bindinput') return { name, id: name, ref: (target) => { console.log('ref', target); if (target) { inputs.current[name as keyof T] = target; } }, defaultValue: initialValues[name], onChange: (ev) => { const { name, value } = ev.target; values.current[name as keyof T] = value; }, } } const onSubmit = (fn: (values: T) => void) => { return (ev: React.FormEvent) => { ev.preventDefault(); fn(getValue()); } } inst.current = { getValue, setValue, setValues, bindInput, onSubmit, }; } return inst.current; } export default useForm;