You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shopify Remix中循环调用useSubmit仅执行一次的问题

Remix中useSubmit循环调用仅执行一次的问题解决

问题原因

你遇到的问题来自两个关键点:

  1. forEach 不会等待异步函数执行完成,所有submit会被几乎同时触发
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 09:40:02