feat: ui 组件 form 支持 autoSubmit (#5695)

* feat: ui 组件 form 支持 autoSubmit

* 下发 onSubmit 否则只能用 handleSubmit 这个会绕过 form 的检测,无法通知到上层
This commit is contained in:
liaoxuezhi 2022-11-04 15:37:29 +08:00 committed by GitHub
parent eb6b49aa1c
commit ee472ec367
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 6 deletions

View File

@ -6,6 +6,7 @@ import {themeable, ThemeProps} from 'amis-core';
import {useForm, UseFormReturn} from 'react-hook-form'; import {useForm, UseFormReturn} from 'react-hook-form';
import {useValidationResolver} from '../hooks/use-validation-resolver'; import {useValidationResolver} from '../hooks/use-validation-resolver';
import {localeable, LocaleProps} from 'amis-core'; import {localeable, LocaleProps} from 'amis-core';
import debounce from 'lodash/debounce';
export type FormRef = React.MutableRefObject< export type FormRef = React.MutableRefObject<
| { | {
@ -16,18 +17,43 @@ export type FormRef = React.MutableRefObject<
export interface FormProps extends ThemeProps, LocaleProps { export interface FormProps extends ThemeProps, LocaleProps {
defaultValues: any; defaultValues: any;
autoSubmit?: boolean;
onSubmit: (value: any) => void; onSubmit: (value: any) => void;
forwardRef?: FormRef; forwardRef?: FormRef;
children?: (methods: UseFormReturn) => JSX.Element | null; children?: (
methods: UseFormReturn & {
onSubmit: (value: any) => void;
}
) => JSX.Element | null;
className?: string; className?: string;
} }
export function Form(props: FormProps) { export function Form(props: FormProps) {
const {classnames: cx, className} = props; const {classnames: cx, className, autoSubmit} = props;
const methods = useForm({ const methods = useForm({
defaultValues: props.defaultValues, defaultValues: props.defaultValues,
resolver: useValidationResolver(props.translate) resolver: useValidationResolver(props.translate)
}); });
let onSubmit = React.useRef<(data: any) => void>(
methods.handleSubmit(props.onSubmit)
);
if (autoSubmit) {
onSubmit = React.useRef(
debounce(methods.handleSubmit(props.onSubmit), 250, {
leading: false,
trailing: true
})
);
React.useEffect(() => {
const subscriber = methods.watch(onSubmit.current);
return () => {
subscriber.unsubscribe();
// debounce 后需要销毁
(onSubmit.current as any)?.cancel?.();
};
}, []);
}
React.useEffect(() => { React.useEffect(() => {
if (props.forwardRef) { if (props.forwardRef) {
@ -53,12 +79,15 @@ export function Form(props: FormProps) {
return ( return (
<form <form
className={cx('Form', className)} className={cx('Form', className)}
onSubmit={methods.handleSubmit(props.onSubmit)} onSubmit={onSubmit.current}
noValidate noValidate
> >
{/* 实现回车自动提交 */} {/* 实现回车自动提交 */}
<input type="submit" style={{display: 'none'}} /> <input type="submit" style={{display: 'none'}} />
{props.children?.(methods)} {props.children?.({
...methods,
onSubmit: onSubmit.current
})}
</form> </form>
); );
} }

View File

@ -33,10 +33,10 @@ const useSubForm = (
// 监控数值变化,自动同步到上层 // 监控数值变化,自动同步到上层
React.useEffect(() => { React.useEffect(() => {
const unsubscribe = methods.watch(() => { const subscriber = methods.watch(() => {
lazySubmit.current(); lazySubmit.current();
}); });
return () => unsubscribe.unsubscribe(); return () => subscriber.unsubscribe();
}, [methods.watch]); }, [methods.watch]);
return methods; return methods;