useEffect React Hook使用异步等待多次渲染(提交按钮)

时间:2019-09-16 23:29:34

标签: javascript reactjs async-await use-effect

我正在尝试基本上禁用“提交”按钮,以使我的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

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

1 个答案:

答案 0 :(得分:1)

遇到任何新问题,都会遇到这个问题:

此第二个数组参数与数据一起传递给useEffect可能导致多重渲染。仅传递数组[],它将呈现一次。

here所述 通过反应官方网站。如果在重新渲染之间未发生某些更改,则可以停止该效果。这样可以防止它多次渲染