react 18.3 useFormState form表单提交
onSubmit={form.handleSubmit(onSubmit)}
const onSubmit = (data: z.infer< typeof EmailPreferenceFormSchema>) => { const formData = new FormData() formData.append( 'emailPreference' , data.emailPreference) formAction(formData) }
import { useFormState } from "react-dom" ; const [state, formAction] = useFormState(EmailPreQuestionFormAction, { errorMessage: "" }); export async function EditQuestionFormAction(prevState: ActionState, formData: FormData): Promise<commonstate<record<string, any="">>> { track( 'editQuestionForm' ); const rawFormData = Object.fromEntries(formData); const parsed = EditQuestionFormSchema.safeParse(rawFormData); if (!parsed.success) { return { error: parsed.error.flatten().fieldErrors, }; } const resp = await PostAction<record<string, any="">>( '/api/person/updatePersonById' , rawFormData); if (resp.errorMessage) { return { errorMessage: resp.errorMessage, }; } return resp }</record<string,></commonstate<record<string,>
注意:18.3版本useFormState 没有自动控制isPending 需要子组件通过useFormStatus 获取pending状态控制submitButton loading,如果需其他可以监听state处理
19版本已经更名为useActionState可以自动处理isPending状态,无需手动处理
const { pending, data, method, action } = useFormStatus();
阻止表单默认提交,表单默认enter事件会刷新页面,禁止表单事件 form的e.preventDefault()不起作用,直接监听form key
useEffect(() => {
//阻止表单默认提交 let documentObj = document.querySelector( '#createListForm' ) as HTMLElement const enterFn = (e: { which: any; keyCode: any; preventDefault: () => void; }) => { var key = e.which || e.keyCode; if (key === 13) { e.preventDefault(); } } documentObj.addEventListener( 'keypress' , enterFn); return () => { documentObj?.removeEventListener( 'keypress' , enterFn) } }, [])