Skip to content

Commit bc56366

Browse files
committed
fix: debouncing not working on empty string
Signed-off-by: Amit Amrutiya <amitamrutiya2210@gmail.com>
1 parent 31ef2a5 commit bc56366

3 files changed

Lines changed: 33 additions & 20 deletions

File tree

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
import CatalogFilterSidebar from './CatalogFilterSidebar';
1+
import CatalogFilterSidebar, { FilterList } from './CatalogFilterSidebar';
22

33
export { CatalogFilterSidebar };
4+
export type { FilterList };

src/custom/StyledSearchBar/StyledSearchBar.tsx

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { SxProps, Theme } from '@mui/material';
22
import { debounce } from 'lodash';
3-
import React, { useEffect, useState } from 'react';
3+
import React, { useEffect, useMemo, useState } from 'react';
44
import { InputAdornment } from '../../base';
55
import { SearchIcon } from '../../icons';
66
import { useTheme } from '../../theme';
@@ -33,44 +33,55 @@ interface SearchBarProps {
3333
*/
3434
function StyledSearchBar({
3535
onChange,
36-
value,
36+
value = '',
3737
label,
3838
sx,
3939
placeholder,
4040
endAdornment,
4141
debounceTime = 300
4242
}: SearchBarProps): JSX.Element {
4343
const theme = useTheme();
44-
const [inputValue, setInputValue] = useState(value ?? '');
44+
const [inputValue, setInputValue] = useState(value);
4545

46+
// Update local state when controlled value changes
4647
useEffect(() => {
47-
if (value !== undefined && value !== inputValue) {
48+
if (value !== inputValue) {
4849
setInputValue(value);
4950
}
50-
// eslint-disable-next-line react-hooks/exhaustive-deps
5151
}, [value]);
5252

53-
useEffect(() => {
54-
const handler = debounce((newValue: string) => {
55-
if (onChange) {
56-
const syntheticEvent = {
57-
target: { value: newValue },
58-
persist: () => {}
59-
} as React.ChangeEvent<HTMLInputElement>;
53+
// Create synthetic event helper
54+
const createSyntheticEvent = (value: string): React.ChangeEvent<HTMLInputElement> =>
55+
({
56+
target: { value },
57+
persist: () => {}
58+
}) as React.ChangeEvent<HTMLInputElement>;
6059

61-
onChange(syntheticEvent);
62-
}
63-
}, debounceTime);
60+
// Memoize the debounced handler
61+
const debouncedOnChange = useMemo(
62+
() =>
63+
debounce((newValue: string) => {
64+
onChange?.(createSyntheticEvent(newValue));
65+
}, debounceTime),
66+
[onChange, debounceTime]
67+
);
6468

65-
handler(inputValue);
69+
useEffect(() => {
70+
if (!onChange) return;
71+
if (inputValue === '') {
72+
onChange(createSyntheticEvent(inputValue));
73+
} else {
74+
debouncedOnChange(inputValue);
75+
}
6676

6777
return () => {
68-
handler.cancel();
78+
debouncedOnChange.cancel();
6979
};
70-
}, [inputValue, onChange, debounceTime]);
80+
}, [inputValue, onChange, debouncedOnChange]);
7181

7282
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
73-
setInputValue(event.target.value);
83+
const newValue = event.target.value;
84+
setInputValue(newValue);
7485
};
7586

7687
return (

src/custom/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import { TransferListProps } from './TransferModal/TransferList/TransferList';
4545
import UniversalFilter, { UniversalFilterProps } from './UniversalFilter';
4646
export { CatalogCard } from './CatalogCard';
4747
export { CatalogFilterSidebar } from './CatalogFilterSection';
48+
export type { FilterList } from './CatalogFilterSection';
4849
export { StyledChartDialog } from './ChartDialog';
4950
export { LearningContent } from './LearningContent';
5051
export { NavigationNavbar } from './NavigationNavbar';

0 commit comments

Comments
 (0)