Fix flash of content when emptying search field
1. Search for something 2. Clear the search bar 3. Quickly start typing something new Before this change, the results would clear on #2, but then the old results would show up again during #3, before the loading state for the new query. This matches the logic, right? We hid the results when both the current and debounced query were empty, and, during that time, neither is empty. Instead, here we update the `useDebounce` hook to have a `forceReset` option, to immediately clear out the value instead of waiting.
This commit is contained in:
parent
701eb33391
commit
11fae604be
2 changed files with 14 additions and 10 deletions
|
@ -91,14 +91,11 @@ function ItemSearchPageResults({ query: latestQuery }) {
|
||||||
const query = useDebounce(latestQuery, 300, {
|
const query = useDebounce(latestQuery, 300, {
|
||||||
waitForFirstPause: true,
|
waitForFirstPause: true,
|
||||||
initialValue: emptySearchQuery,
|
initialValue: emptySearchQuery,
|
||||||
});
|
|
||||||
|
|
||||||
// We'll skip all this if the query is empty. We also check the latest query
|
// When the query is empty, clear the debounced query immediately too! That
|
||||||
// for this, without waiting for the debounce, in order to get fast feedback
|
// will give us fast feedback when the search field clears.
|
||||||
// when clearing the query. But we _do_ still check the debounced query too,
|
forceReset: searchQueryIsEmpty(latestQuery),
|
||||||
// which gives us _slow_ feedback when moving from empty to _non_-empty.
|
});
|
||||||
const skipSearchResults =
|
|
||||||
searchQueryIsEmpty(query) || searchQueryIsEmpty(latestQuery);
|
|
||||||
|
|
||||||
// NOTE: This query should always load ~instantly, from the client cache.
|
// NOTE: This query should always load ~instantly, from the client cache.
|
||||||
const { data: zoneData } = useQuery(gql`
|
const { data: zoneData } = useQuery(gql`
|
||||||
|
@ -147,11 +144,11 @@ function ItemSearchPageResults({ query: latestQuery }) {
|
||||||
zoneIds: filterToZoneIds,
|
zoneIds: filterToZoneIds,
|
||||||
},
|
},
|
||||||
context: { sendAuth: true },
|
context: { sendAuth: true },
|
||||||
skip: skipSearchResults,
|
skip: searchQueryIsEmpty(query),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (skipSearchResults) {
|
if (searchQueryIsEmpty(query)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ export function safeImageUrl(urlString) {
|
||||||
export function useDebounce(
|
export function useDebounce(
|
||||||
value,
|
value,
|
||||||
delay,
|
delay,
|
||||||
{ waitForFirstPause = false, initialValue = null } = {}
|
{ waitForFirstPause = false, initialValue = null, forceReset = false } = {}
|
||||||
) {
|
) {
|
||||||
// State and setters for debounced value
|
// State and setters for debounced value
|
||||||
const [debouncedValue, setDebouncedValue] = React.useState(
|
const [debouncedValue, setDebouncedValue] = React.useState(
|
||||||
|
@ -165,6 +165,13 @@ export function useDebounce(
|
||||||
[value, delay] // Only re-call effect if value or delay changes
|
[value, delay] // Only re-call effect if value or delay changes
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// The `forceReset` option sets the value immediately!
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (forceReset) {
|
||||||
|
setDebouncedValue(value);
|
||||||
|
}
|
||||||
|
}, [value, forceReset]);
|
||||||
|
|
||||||
return debouncedValue;
|
return debouncedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue