Skip to content

Use functional setState in async handlers to prevent stale closures in connector hook #1006

@MODSetter

Description

@MODSetter

Description

In use-search-source-connectors.ts, the createConnector, updateConnector, deleteConnector, and indexConnector functions all close over the connectors state variable. Since these are async functions that await network requests, if two operations run concurrently the second will use a stale snapshot of connectors, potentially losing the first operation's update.

Vercel React Best Practices Rule: rerender-functional-setstate (5.9)

File to change

  • surfsense_web/hooks/use-search-source-connectors.ts

What to do

Replace each direct state reference with a functional updater:

createConnector (lines 187-190):

const newConnector = await response.json();
setConnectors(prev => {
  const updated = [...prev, newConnector];
  updateConnectorSourceItems(updated);
  return updated;
});
return newConnector;

updateConnector (lines 221-226):

const updatedConnector = await response.json();
setConnectors(prev => {
  const updated = prev.map(c => c.id === connectorId ? updatedConnector : c);
  updateConnectorSourceItems(updated);
  return updated;
});
return updatedConnector;

deleteConnector (lines 251-253):

setConnectors(prev => {
  const updated = prev.filter(c => c.id !== connectorId);
  updateConnectorSourceItems(updated);
  return updated;
});

indexConnector (lines 297-306):

setConnectors(prev =>
  prev.map(c => c.id === connectorId
    ? { ...c, last_indexed_at: new Date().toISOString() }
    : c
  )
);

Acceptance criteria

  • No function in the hook directly references connectors state variable (only uses prev inside the updater)
  • Creating, updating, deleting, and indexing connectors still work correctly
  • Rapid sequential operations (e.g., delete two connectors quickly) don't lose data

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions