Description
Calling refresh() on the useAgentList hook resets internal state to the initial loading state but never actually re-fetches data. The list spinner spins forever.
Steps to Reproduce
- Open the homepage (uses
useAgentList).
- Wait for the agent list to populate.
- Click any UI control wired to
refresh() (e.g., the manual refresh button on HomePage).
- Observe the list goes blank and the loading spinner appears — and stays.
Expected vs Actual
- Expected: After
refresh(), the hook should re-issue the scan and repopulate the list.
- Actual: The hook resets to
initialState but never re-runs the data-fetching effect, leaving the UI permanently in the loading state.
Root Cause
frontend/src/hooks/useAgentList.ts around lines 139–141:
function refresh(): void {
setState(initialState);
}
The fetch is wired up via a useEffect whose dependency array is [client, v2Client, marketplaceClient]. None of these references change when refresh() is called, so the effect doesn't re-fire. setState(initialState) re-renders, but with no fetch behind it the loading state is permanent.
Suggested Fix
Add a refreshKey counter to state and include it in the effect's dependency array:
const [refreshTick, setRefreshTick] = useState(0);
function refresh() { setState(initialState); setRefreshTick(t => t + 1); }
useEffect(() => { /* ...existing... */ }, [client, v2Client, marketplaceClient, refreshTick]);
Environment
- React 18, Vite, ethers v6
- File:
frontend/src/hooks/useAgentList.ts
- Severity: High — refresh is broken across all consumers of the hook
Related
There's also a closure-staleness issue in loadMore (line ~110) that reads state.nextScanId from the closure rather than from a functional updater. Calling loadMore twice in quick succession causes duplicate appends. Happy to file separately if useful.
Description
Calling
refresh()on theuseAgentListhook resets internal state to the initial loading state but never actually re-fetches data. The list spinner spins forever.Steps to Reproduce
useAgentList).refresh()(e.g., the manual refresh button onHomePage).Expected vs Actual
refresh(), the hook should re-issue the scan and repopulate the list.initialStatebut never re-runs the data-fetching effect, leaving the UI permanently in the loading state.Root Cause
frontend/src/hooks/useAgentList.tsaround lines 139–141:The fetch is wired up via a
useEffectwhose dependency array is[client, v2Client, marketplaceClient]. None of these references change whenrefresh()is called, so the effect doesn't re-fire.setState(initialState)re-renders, but with no fetch behind it the loading state is permanent.Suggested Fix
Add a
refreshKeycounter to state and include it in the effect's dependency array:Environment
frontend/src/hooks/useAgentList.tsRelated
There's also a closure-staleness issue in
loadMore(line ~110) that readsstate.nextScanIdfrom the closure rather than from a functional updater. CallingloadMoretwice in quick succession causes duplicate appends. Happy to file separately if useful.