diff --git a/.changeset/fix-catalog-filter-flicker.md b/.changeset/fix-catalog-filter-flicker.md new file mode 100644 index 0000000000..5964f7ada9 --- /dev/null +++ b/.changeset/fix-catalog-filter-flicker.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Fixed a UI flicker in the catalog entity list where changing a filter would briefly flash stale data before showing the new results. diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx index 12eb9dff6c..a18575befa 100644 --- a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx +++ b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx @@ -454,30 +454,36 @@ export const EntityListProvider = ( [paginationMode], ); + // Use resolvedValue directly when available to avoid an extra render cycle. + // Without this, there's a render where loading has flipped back to false but + // outputState hasn't been updated yet (it syncs via useEffect), causing a + // flash of stale data between the loading state and the new results. + const latestOutput = resolvedValue ?? outputState; + const pageInfo = useMemo(() => { if (paginationMode !== 'cursor') { return undefined; } - const prevCursor = outputState.pageInfo?.prevCursor; - const nextCursor = outputState.pageInfo?.nextCursor; + const prevCursor = latestOutput.pageInfo?.prevCursor; + const nextCursor = latestOutput.pageInfo?.nextCursor; return { prev: prevCursor ? () => setCursor(prevCursor) : undefined, next: nextCursor ? () => setCursor(nextCursor) : undefined, }; - }, [paginationMode, outputState.pageInfo]); + }, [paginationMode, latestOutput.pageInfo]); const value = useMemo( () => ({ - filters: outputState.appliedFilters, - entities: outputState.entities, - backendEntities: outputState.backendEntities, + filters: latestOutput.appliedFilters, + entities: latestOutput.entities, + backendEntities: latestOutput.backendEntities, updateFilters, queryParameters, loading, error, pageInfo, - totalItems: outputState.totalItems, + totalItems: latestOutput.totalItems, limit, offset, setLimit, @@ -485,7 +491,7 @@ export const EntityListProvider = ( paginationMode, }), [ - outputState, + latestOutput, updateFilters, queryParameters, loading,