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

如何在同一组件的多个SWR请求中使用isValidating

问题:如何在单个组件内的两个独立API请求中使用isValidating?

我有一个展示未完成订单和已完成订单的仪表盘组件,需要调用两个不同的接口(一个获取未完成订单,一个获取已完成订单)。我希望使用isValidating来检查两个API响应的状态,并据此显示加载动画。

原代码:

//Order Dashboard Component
import Callout from '../components/cards/Callout';

function OrdersDashboard() {
    const ordersEndpoint = `${BASE_URL}/orders`;
    const openOrdersEndpoint = `${ordersEndpoint}&completed=false`;
    const completedOrdersEndpoint = `${orderEndpoint}&completed=true`;

    //Endpoint #1
    const {
        data: openOrders,
        error: openOrdersError,
        isValidating,
    } = useSWR([openOrdersEndpoint, BASE_URL], ([url, audience]) =>
        fetchData(url, audience)
    );

    //Endpoint #2
    const {
        data: completedOrders,
        error: completedOrdersError,
        isValidating,
    } = useSWR([completedOrdersEndpoint, BASE_URL], ([url, audience]) =>
        fetchData(url, audience)
    );

    if (completedOrdersError || openOrdersError) {
        return <div>Error</div>;
    }

    if (!completedOrders && !openOrders) {
        return <div>Loading...</div>;
    }

    return (
        <>
            <h1>Orders Dashboard</h1>
            <section id='openOrders' className='section'>
                {!openOrders || !openOrders.length ? (
                    <>
                        <h2>Open Orders</h2>
                        <Callout
                            message='No Open Orders'
                            isValidating={isValidating}
                        />
                    </>
                ) : (
                    <DataTable columns={columns} data={openOrders} />
                )}
            </section>

            <section id='completedOrders' className='section'>
                {!completedOrders || !completedOrders.length ? (
                    <>
                        <h2>Completed Orders </h2>
                        <Callout
                            message='No Completed Orders'
                            isValidating={isValidating}
                        />
                    </>
                ) : (
                    <DataTable columns={columns} data={completedOrders} />
                )}
            </section>
        </>
    );
}
解决方案

你的核心问题是两个useSWR调用都直接解构了isValidating变量,后面的变量会覆盖前面的,导致无法区分两个请求的验证状态。只需给每个isValidating设置别名,就能分别控制两个请求的加载状态:

1. 给每个isValidating重命名

在解构时用别名区分两个请求的验证状态:

// 未完成订单请求
const {
    data: openOrders,
    error: openOrdersError,
    isValidating: isOpenOrdersValidating, // 重命名
} = useSWR([openOrdersEndpoint, BASE_URL], ([url, audience]) =>
    fetchData(url, audience)
);

// 已完成订单请求
const {
    data: completedOrders,
    error: completedOrdersError,
    isValidating: isCompletedOrdersValidating, // 重命名
} = useSWR([completedOrdersEndpoint, BASE_URL], ([url, audience]) =>
    fetchData(url, audience)
);

2. 分别传递对应状态到组件

现在可以给每个区域的Callout组件传递各自的验证状态:

<section id='openOrders' className='section'>
    {!openOrders || !openOrders.length ? (
        <>
            <h2>未完成订单</h2>
            <Callout
                message='暂无未完成订单'
                isValidating={isOpenOrdersValidating}
            />
        </>
    ) : (
        <DataTable columns={columns} data={openOrders} />
    )}
</section>

<section id='completedOrders' className='section'>
    {!completedOrders || !completedOrders.length ? (
        <>
            <h2>已完成订单</h2>
            <Callout
                message='暂无已完成订单'
                isValidating={isCompletedOrdersValidating}
            />
        </>
    ) : (
        <DataTable columns={columns} data={completedOrders} />
    )}
</section>

3. 优化全局加载判断(可选)

原代码中!completedOrders && !openOrders的判断有缺陷:如果其中一个请求先返回数据,另一个仍在加载,这个判断会失效。改用两个isValidating的逻辑或,能更准确判断全局加载状态:

if (isOpenOrdersValidating || isCompletedOrdersValidating) {
    return <div>加载中...</div>;
}

完整修改后的代码

// 订单仪表盘组件
import Callout from '../components/cards/Callout';

function OrdersDashboard() {
    const ordersEndpoint = `${BASE_URL}/orders`;
    const openOrdersEndpoint = `${ordersEndpoint}&completed=false`;
    const completedOrdersEndpoint = `${ordersEndpoint}&completed=true`; // 修正原代码笔误:orderEndpoint改为ordersEndpoint

    // 接口1:未完成订单
    const {
        data: openOrders,
        error: openOrdersError,
        isValidating: isOpenOrdersValidating,
    } = useSWR([openOrdersEndpoint, BASE_URL], ([url, audience]) =>
        fetchData(url, audience)
    );

    // 接口2:已完成订单
    const {
        data: completedOrders,
        error: completedOrdersError,
        isValidating: isCompletedOrdersValidating,
    } = useSWR([completedOrdersEndpoint, BASE_URL], ([url, audience]) =>
        fetchData(url, audience)
    );

    // 错误处理
    if (completedOrdersError || openOrdersError) {
        return <div>加载失败,请稍后重试</div>;
    }

    // 全局加载状态
    if (isOpenOrdersValidating || isCompletedOrdersValidating) {
        return <div>加载中...</div>;
    }

    return (
        <>
            <h1>订单仪表盘</h1>
            <section id='openOrders' className='section'>
                {!openOrders || !openOrders.length ? (
                    <>
                        <h2>未完成订单</h2>
                        <Callout
                            message='暂无未完成订单'
                            isValidating={isOpenOrdersValidating}
                        />
                    </>
                ) : (
                    <DataTable columns={columns} data={openOrders} />
                )}
            </section>

            <section id='completedOrders' className='section'>
                {!completedOrders || !completedOrders.length ? (
                    <>
                        <h2>已完成订单</h2>
                        <Callout
                            message='暂无已完成订单'
                            isValidating={isCompletedOrdersValidating}
                        />
                    </>
                ) : (
                    <DataTable columns={columns} data={completedOrders} />
                )}
            </section>
        </>
    );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:35:01