基于isFetching而非isLoading使用react-admin骨架屏时状态异常切换问题
React-admin 骨架屏基于isFetching实现时状态频繁切换的问题解决
在react-admin列表页面尝试用isFetching替代isLoading实现骨架屏,但isFetching状态持续在true和false之间来回切换,导致骨架屏闪烁或无法正常显示。
问题代码片段
const listContext = useListController(); const { isFetching, isLoading } = listContext; {isFetching ? ( <Skeleton variant="rectangular" width={210} height={118} /> ) : ( <List {...props} filters={PostFilter} actions={<ListActions listFilter={PostFilter} />} sx={ListStyles} > <Datagrid> {/* 数据列定义 */} </Datagrid> </List> )}
原因分析
isFetching的特性:react-admin中isFetching会在每次发起数据请求(包括分页、筛选、排序,甚至组件内部的重复请求)时变为true,请求结束后立即切回false。如果直接用它控制骨架屏,任何频繁的请求都会导致状态反复切换。- 上下文冲突:外部单独调用
useListController获取的上下文,和List组件内部创建的上下文可能不同步,导致状态判断逻辑混乱。
解决方案
方案1:使用List组件的children函数模式
直接在List内部获取同步的状态,避免上下文不一致问题:
<List {...props} filters={PostFilter} actions={<ListActions listFilter={PostFilter} />} sx={ListStyles} > {({ isFetching, data }) => isFetching && data.length === 0 ? ( <Skeleton variant="rectangular" width={210} height={118} /> ) : ( <Datagrid> {/* 数据列定义 */} </Datagrid> ) } </List>
方案2:结合isLoading和数据状态判断
只在初始加载或无数据且正在请求时显示骨架屏,避免频繁切换:
const listContext = useListController(); const { isFetching, isLoading, data } = listContext; // 仅在初始加载,或数据为空且正在请求时展示骨架屏 const showSkeleton = isLoading || (isFetching && data.length === 0); return ( <> {showSkeleton ? ( <Skeleton variant="rectangular" width={210} height={118} /> ) : ( <List {...props} filters={PostFilter} actions={<ListActions listFilter={PostFilter} />} sx={ListStyles} > <Datagrid> {/* 数据列定义 */} </Datagrid> </List> )} </> );
方案3:排查重复请求原因
检查是否存在组件不必要的重渲染,或List组件的props频繁变化导致重复触发请求:
- 用
React.memo包裹ListActions、PostFilter等子组件,减少不必要的重渲染 - 优化props传递,避免传递不稳定的引用(比如内联函数、对象)
内容的提问来源于stack exchange,提问作者Mayar Ahmed
相关产品推荐
相关产品推荐

