首页 > 解决方案 > useEffect React Hook 使用异步等待多次渲染(提交按钮)

问题描述

我试图基本上禁用提交按钮,所以我的 api 调用只被触发一次/在操作已经进行时有人不能再次点击提交。

我将 runOnSubmit 函数转换为异步函数并直接调用它。我已经基于许多其他解决方案,基本上当我这样做和调试时,我可以说 isSubmitting 仍然设置为 true 并且钩子被多次调用/ submitAsync 函数被调用两次。

基本上, setSubmitting 会被调用,但实际上在再次刷新之前不会做任何事情。我希望它只被调用一次。我不知道为什么 submitAsync 甚至会运行多次,因为依赖项(错误)没有改变。如果他们正在改变,那么 noErrors 第二次会有所不同,它甚至不会击中那个块。

useEffect(() => {

        if (isSubmitting) {
            const noErrors = Object.keys(errors).length === 0;
            if (noErrors) {

                const submitAsync = async () => {
                    await runOnSubmit()
                    setSubmitting(false)
                }

                // clear out touched upon submission
                setTouched([]);
                submitAsync();
            } else {
                setSubmitting(false);
            }
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [errors]);

更新-添加更多信息:

 // function for form submission
    const handleSubmit = (event) => {
        event.preventDefault();
        const validationErrors = validate(values);
        setErrors(validationErrors);
        setSubmitting(true);
    }

由于此函数将 Submitting 设置为 true,它应该重新运行 useEffect 函数,因为 isSubmitting 在依赖数组中。

按钮调用提交并禁用它:

<Button 
 disabled={isSubmitting} 
 buttonType="submit" 
 text="Create Account" />

我的按钮组件:

<button 
  type={props.buttonType}
  disabled={props.disabled}
  onClick={props.onClick}>
     {props.text}
 </button>

第二次编辑-在 console.logs 中添加:

useEffect(() => {
        console.log("use effect running", isSubmitting)
        if (isSubmitting) {
            console.log("use effect submitting true")
            const noErrors = Object.keys(errors).length === 0;
            if (noErrors) {
                console.log("use effect no errors")
                const submitAsync = async () => {
                    console.log("inside submit async")
                    await runOnSubmit()
                    console.log("after function")
                    setSubmitting(false)
                    console.log("after set false")
                }

                // clear out touched upon submission
                setTouched([]);
                submitAsync();
                console.log("console after submit")
            } else {
                setSubmitting(false);
            }
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [isSubmitting === true]);

运行时:

use effect running true
use effect submitting true
use effect no errors
inside submit async
the user called signup method
console after submit
after function
after set false
use effect running false

这里没有多大意义的问题是“提交后的控制台”在“函数后”之前运行。就好像异步等待没有做任何事情。

标签: javascriptreactjsasync-awaituse-effect

解决方案


TO ANY NEW PERON HAVING THIS PROBLEM:

This second array argument passed to useEffect with data could be causing the multiple render. Pass in only an array [] and it will render once.

As stated here by react official site. The effect can be stopped if certain changes have not occurred between re-renders. This will prevent it from rendering multiple times


推荐阅读