reactjs 如何在React Hook表单中动态组合/链接多个'handleSubmit'方法?

ldioqlga  于 2023-01-08  发布在  React
关注(0)|答案(1)|浏览(109)

我的表单组件中有多个useForm钩子,我想创建一个方法来动态处理任意数量钩子的一个submit按钮,其思想是部分表单应该被连续验证。
对于孤立的场景,此方法有效:

import React from 'react'
import { useForm } from 'react-hook-form'

const MyFormComponent = () => {

   const form1 = useForm();
   const form2 = useForm();

   const onSubmitSuccess = () => {
      //some success logic
   };

   const handleMultiple = form1.handleSubmit(form2.handleSubmit(onSubmitSuccess));

   return <React.Fragment>
      {
         ...form1Fields
      }

      {
         ...form2Fields
      }

      <button onClick={handleMultiple}>submit</button>
   </React.Fragment>
}

现在我想创建一个泛型'handleMultiple'。我尝试使用redux 'compose'函数,但是这种方法忽略了验证:

import { compose } from 'redux'

const getHandleMultiple = (submitFunc, ...forms) => {
   const handleMultiple = compose(
      ...forms.map(form => form.handleSubmit),
      submitFunc
   );

   return {
      handleMultiple
   }
}

有什么想法如何存档这一点?不同的方法也赞赏。
编辑:我试着用'useMemo'钩子来 Package compose方法,就像@AhmedI.Elsayed建议的那样,但这并没有解决问题:

const useComposedFormSubmit = (submitFunc, ...forms) => {
    const handleComposedSubmit = useMemo(() => {
        
        return compose(
            ...forms.map(form => form.handleSubmit), 
            submitFunc
        )

    }, [forms, submitFunc])

    return { 
        handleComposedSubmit
    }
}

编辑2:代码沙盒:https://codesandbox.io/s/react-hook-form-compose-handlesubmit-yes5y9

mwyxok5s

mwyxok5s1#

Edit 1:handleSubmit会在onSubmit上被调用,并且会在每个handleSubmit上重复调用,这基本上就像我们用数学方法将其表示为:

handleSubmit2(handleSubmit1(onSubmit))(x)

但是作曲呢

compose(...forms.map((form) => form.handleSubmit), submitFunc);

这是

handler2(handler1(submitFunc(x)))

如果我们按相反的顺序作曲

submitFunc(handler1(handler2(x)))

这仍然不是我们所需要的,我们需要做的是忽略compose,因为这不是我们所需要的,然后实现我们自己的函数。

const useComposedFormSubmit = (submitFunc, ...forms) => {
  return useMemo(() => {
    const fns = [...forms.map(f => f.handleSubmit)];
    return fns.reduce((p, c) => {
      return c(p);
    }, submitFunc); 
  }, [submitFunc, forms]); 
};

无简化版本

const useComposedFormSubmit = (submitFunc, ...forms) => {
  return useMemo(() => {
    const fns = [...forms.map(f => f.handleSubmit)];
    let resultFunc = submitFunc;

    for (const fn of fns) {
      resultFunc = fn(resultFunc);
    }

    return resultFunc;
  }, [submitFunc, forms]); 
};
旧答案,不起作用,但解释了如何在compose中表示OP POST

我认为这个问题是由于表单在某个时候没有定义,不确定,但是你可以测试这个,我很确定它应该工作,这是一个钩子。钩子应该从use开始,就像文档中描述的那样。

const useMultipleSubmitters = (submitFunc, ...forms) => {
   return useMemo(() => {
      return compose(...forms.map(f => form.handleSubmit), submitFunc)
    }, [forms, submitFunc])
}

并根据需要进行调整。它与您的相同,但会重新计算重新渲染。

相关问题