在 Next.js 应用程序中阻止多个表单提交/取消对表单提交的提取请求

Block multiple form submissions/ debounce a fetch request on form submit in Next.js app

我的 Next.js 应用程序中有一个注册表单。

不良行为:如果用户快速连续多次单击“注册”提交按钮,应用程序会发出多个提取请求,并在界面上显示多个 toast。

期望的行为:在第一次提交完成之前,用户在按下提交后不能执行任何操作。

我的第一个想法是使 API 调用同步。但是由于我不完全理解的原因,这似乎被认为是一个坏主意:

我已经按照类似的思路查看了其他问题,但答案没有帮助:

我不太明白为什么同步请求不是这里的最佳做法。当然,我在 I/O 操作期间阻止了 CPU,但我不希望页面在表单提交完成之前执行任何操作?

防止表单提交时开关反弹的推荐方法是什么?您能解释一下原因吗?

src/pages/auth/sign-up.js:

const onSubmit = async (data) => {
  const { email, password1, password2, first_name, last_name } = data;

  const response = await postSignUp( email, password1, password2, first_name, last_name );

  // error handling code

  toast.success('You have successfully registered!', { autoClose: 2500 })

  setTimeout( () => {
    router.push({ pathname: '/auth/verify-email', query: { email: email } });
  }, 2500 )

/src/lib/api.js:

export async function postSignUp(email, password1, password2, first_name, last_name) {
  const response = await fetch(SIGN_UP_ENDPOINT, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify( { email, password1, password2, first_name, last_name } ),
  });

  const json = await response.json();
  return json;
}

一个非常简单且常用的方法是禁用提交按钮,直到您从 API 收到响应。所以,例如:

创建状态:

const [isSubmitting, setIsSubmitting] = useState(false);

使用该状态设置提交按钮的 disabled 属性:

<button type="submit" disabled={isSubmitting}>Save</button>

从您的事件处理程序调用 setIsSubmitting

const onSubmit = async (data) => {
  setIsSubmitting(true);

  const { email, password1, password2, first_name, last_name } = data;

  const response = await postSignUp( email, password1, password2, first_name, last_name );

  // error handling code

  toast.success('You have successfully registered!', { autoClose: 2500 })

  setTimeout( () => {
    router.push({ pathname: '/auth/verify-email', query: { email: email } });
  }, 2500 )

  setIsSubmitting(false);
}