如何在同一组件的多个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
相关产品推荐
相关产品推荐

