-
-
Notifications
You must be signed in to change notification settings - Fork 899
Description
🐛 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:
volto/packages/volto/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx
Lines 96 to 101 in e07a6c8
| 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:
- First from the UI component (e.g. Facets / FilterList)
- 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:
- UI updates state first, then calls
onTriggerSearch - 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
onTriggerSearchis the single source of truth for state updates - Or state updates must always happen outside it