I was given a new task and I have to debounce the input value to prevent a backend request on each keystroke and on the other hand CollectionsAutocomplete should have an internal useState with an input value, that is linked to the generalQuery variable.
Right now I was able to add the internal useState but I don’t know how to apply the debounce.
The CollectionsAutocomplete is a component that is located in our library and I use it in a different project.
Here is the CollectionsAutocomplete in the library:
type CollectionsAutocompleteProps = GenericFetchAutocompletePropsWrapperType<StyleCollection>
& {
targetBrandNumber: string;
queryVariables?: Exact<{
brandNumber: string;
generalQuery?: InputMaybe<string> | undefined;
pagination: PaginationInput;
}> | undefined;
onInputChange?: (inputValue: string) => void;
};
export const CollectionsAutocomplete = (props: CollectionsAutocompleteProps): ReactElement => {
const { queryVariables, targetBrandNumber, value, handleOnBlur, handleOnChange, handleOnFocus, limitTags, onInputChange } = props;
const [inputValue, setInputValue] = useState<string>('');
return (
<GenericFetchAutocomplete<
StyleCollection,
GetAllCollectionsQuery,
GetAllCollectionsQueryVariables,
true>
limitTags={limitTags}
value={value}
dataMapper={(data): Array<StyleCollection> =>
data.collections?.edges?.map((edge) => edge?.node).filter(sortUtil.isDefined) ?? []}
fetchQuery={GetAllCollectionsDocument}
inputLabels={{
plural: 'Collections',
single: 'Collection',
}}
queryOptions={{
fetchPolicy: 'network-only',
context: { clientName: GraphClientNames['backend'] },
variables: {
generalQuery: queryVariables?.generalQuery ?? inputValue,
brandNumber: targetBrandNumber,
pagination: {
first: 100,
after: null,
},
...queryVariables ?? {},
},
}}
tagLabelFormatter={(option): string => `${option.collectionTerm} (${option.collectionName})`}
textFieldProps={{
...props.textFieldProps,
placeholder: value.length === 0 ? 'Select' : '',
sx: {
['& ::placeholder']: {
color: '',
},
},
}}
idKey='collectionNumber'
optionLabelFormatter={(option): string => `${option.collectionTerm} (${option.collectionName})`}
multiple
onBlur={handleOnBlur}
onChange={handleOnChange}
onFocus={handleOnFocus}
onInputChange={(event): void => {
const newValue = (event.target as HTMLInputElement).value;
setInputValue(newValue);
onInputChange?.(newValue);
}}
/>
);
};
here is how I use the CollectionsAutocomplete in my project:
<CollectionsAutocomplete
value={collectionsValue}
textFieldProps={{ required: true }}
targetBrandNumber={selectedBrands[0]?.brandNumber}
queryVariables={{
pagination: {
first: 200,
after: null,
},
}}
handleOnChange={(e, v): void => {
if (v !== null) {
setCollectionsValue(v);
} else {
setCollectionsValue([]);
}
}}
onInputChange={(newValue: string): void => {
console.log('Input value changed:', newValue);
}}
/>
I’m a bit lost about how to apply the logic.