Skip to content

🐛 Potential double search trigger when combining setFacets and onTriggerSearch #7953

@alexandreIFB

Description

@alexandreIFB

🐛 Potential double search trigger when combining setFacets and onTriggerSearch

Description

While working with the Search block and custom facet integrations, we noticed a potential double-trigger scenario when setFacets is called before onTriggerSearch.

In the core TopSideFacets implementation, the following pattern is used:

setFacets={(f) => {
flushSync(() => {
setFacets(f);
onTriggerSearch(searchedText || '', f);
});
}}

However, inside withSearch, the onTriggerSearch implementation contains:

if (toSearchFacets) setFacets(toSearchFacets);

This means that when setFacets is called externally and onTriggerSearch is called immediately after, setFacets may be executed twice:

  1. First from the UI component (e.g. Facets / FilterList)
  2. Second inside onTriggerSearch

Depending on how the project integrates withQueryString, this may lead to:

  • Two state updates
  • Two URL updates
  • Two search dispatches
  • Duplicate API calls

Why this happens

The current design allows two usage patterns:

  1. UI updates state first, then calls onTriggerSearch
  2. UI calls only onTriggerSearch, and it updates state internally

Since both are supported simultaneously, duplication can occur.


Suggested improvement

Make the state update inside onTriggerSearch idempotent:

if (toSearchFacets && !isEqual(toSearchFacets, facets)) {
  setFacets(toSearchFacets);
}

This keeps backward compatibility while preventing duplicate updates.

Alternatively, consider clearly defining a single responsibility pattern:

  • Either onTriggerSearch is the single source of truth for state updates
  • Or state updates must always happen outside it

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions