Shopify Remix中循环调用useSubmit仅执行一次的问题
Remix中useSubmit循环调用仅执行一次的问题解决
问题原因
你遇到的问题来自两个关键点:
forEach不会等待异步函数执行完成,所有submit会被几乎同时触发- Remix的
useSubmit在连续调用时,会取消之前未完成的同页面action请求,最终只有一次请求能完成
解决方案
方案1:使用for...of顺序执行请求
把forEach替换成for...of循环,确保每个请求完成后再发起下一个,避免请求被中断:
export default function Index() { const submit = useSubmit(); const handleBatchSubmit = async () => { for (const [index, row] of rows.entries()) { console.log('row' + index); await submit(row, { replace: false, method: "POST" }); // 可选:添加间隔避免请求过于频繁 // await new Promise(resolve => setTimeout(resolve, 100)); } }; // 可在组件挂载或点击事件中触发批量提交 useEffect(() => { handleBatchSubmit(); }, []); return <div>导入模块内容</div>; }
方案2:合并请求(更高效)
如果不需要逐行单独提交,建议把所有行数据合并成一个请求,减少服务器压力:
export default function Index() { const submit = useSubmit(); const handleBatchSubmit = () => { submit({ rows: JSON.stringify(rows) }, { replace: false, method: "POST" }); }; return <button onClick={handleBatchSubmit}>批量导入</button>; }
对应的action修改为批量处理逻辑:
export async function action({ request, params }) { const formData = await request.formData(); const rows = JSON.parse(formData.get('rows')); // 批量处理每一行数据 rows.forEach((row) => { console.log(new Date().getTime()); // 这里添加单条数据的处理逻辑 }); return json({ result: 1 }); }
补充说明
forEach遍历异步函数时,会直接跳过await逻辑,一次性触发所有submit请求,而Remix的submit机制会中断之前未完成的同页面action请求,导致只有一次请求能执行完成。- 合并请求是更优的方案,既减少HTTP请求次数,也从根源上避免了请求被取消的问题。
内容的提问来源于stack exchange,提问作者ariel
相关产品推荐
相关产品推荐

