在 Next.js 应用程序中阻止多个表单提交/取消对表单提交的提取请求
Block multiple form submissions/ debounce a fetch request on form submit in Next.js app
我的 Next.js 应用程序中有一个注册表单。
不良行为:如果用户快速连续多次单击“注册”提交按钮,应用程序会发出多个提取请求,并在界面上显示多个 toast。
期望的行为:在第一次提交完成之前,用户在按下提交后不能执行任何操作。
我的第一个想法是使 API 调用同步。但是由于我不完全理解的原因,这似乎被认为是一个坏主意:
- 在这里看到唯一的答案,建议不要这样做:How to make javascript fetch synchronous?
我已经按照类似的思路查看了其他问题,但答案没有帮助:
- 请参阅 How to prevent form from submitting multiple times from client side? 当存在表单验证时,最佳答案不起作用的地方。并使用 JQuery.
我不太明白为什么同步请求不是这里的最佳做法。当然,我在 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);
}
我的 Next.js 应用程序中有一个注册表单。
不良行为:如果用户快速连续多次单击“注册”提交按钮,应用程序会发出多个提取请求,并在界面上显示多个 toast。
期望的行为:在第一次提交完成之前,用户在按下提交后不能执行任何操作。
我的第一个想法是使 API 调用同步。但是由于我不完全理解的原因,这似乎被认为是一个坏主意:
- 在这里看到唯一的答案,建议不要这样做:How to make javascript fetch synchronous?
我已经按照类似的思路查看了其他问题,但答案没有帮助:
- 请参阅 How to prevent form from submitting multiple times from client side? 当存在表单验证时,最佳答案不起作用的地方。并使用 JQuery.
我不太明白为什么同步请求不是这里的最佳做法。当然,我在 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);
}