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

React异步函数setState批处理问题求助(Next.js场景)

解决Next.js客户端组件表单提交时Loading状态不显示的问题

核心问题:React在异步函数中会对setState调用进行批处理。你代码中await前的两次状态更新(禁用按钮、设置Loading文本)会被合并处理,而await后的状态更新会立即触发渲染,导致Loading状态还没来得及展示就被覆盖,看起来像是直接跳过了步骤1。

解决方案

方法1:使用flushSync强制同步更新

导入React的flushSync工具,将await前的状态更新包裹起来,强制React立即执行状态更新并渲染UI,而非批处理:

import { flushSync } from 'react';

async function Execute(data: FormData)
{
    flushSync(() => {
        SetInteractable(false);
        setMessage("Loading");
    });

    const response = await SendGiftAction(data);

    SetInteractable(true);
    setMessage(response.Success ? "" : response.Error);
}

方法2:利用微任务延迟Server Action调用

通过await Promise.resolve()让状态更新的渲染先完成,再执行Server Action,本质是利用JavaScript微任务队列的执行顺序:

async function Execute(data: FormData)
{
    SetInteractable(false);
    setMessage("Loading");

    // 等待状态更新完成渲染
    await Promise.resolve();

    const response = await SendGiftAction(data);

    SetInteractable(true);
    setMessage(response.Success ? "" : response.Error);
}

修改后的完整组件代码

"use client";

import { SendGiftAction } from "@/app/actions/SendGiftAction";
import { useState, flushSync } from "react";

export default function GoldGiftForm()
{
    const [interactable, setInteractable] = useState(true);
    const [message, setMessage] = useState("");

    async function Execute(data: FormData)
    {
        flushSync(() => {
            setInteractable(false);
            setMessage("Loading");
        });

        const response = await SendGiftAction(data);

        setInteractable(true);
        setMessage(response.Success ? "" : response.Error);
    }

    return (
        <form action={Execute}>
            <h3>Send Gold Gift</h3>

            <input
                name="userID"
                type="text"
                placeholder="User ID"
            />

            <input
                name="gold"
                type="number"
                placeholder="Gold"
            />

            <button type="submit" disabled={!interactable}> Send Gift </button>

            <p>{message}</p>
        </form>
    );
}

内容的提问来源于stack exchange,提问作者Moe Baker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:54:56