Skip to content

Commit 680a777

Browse files
authored
Merge pull request #764 from amitamrutiya/fix-debouncing
Fix debouncing cleanup issue in styled search bar
2 parents bf8f47b + 1a57213 commit 680a777

1 file changed

Lines changed: 31 additions & 14 deletions

File tree

src/custom/StyledSearchBar/StyledSearchBar.tsx

Lines changed: 31 additions & 14 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, { useCallback, useState } from 'react';
3+
import React, { useEffect, useState } from 'react';
44
import { InputAdornment } from '../../base';
55
import { SearchIcon } from '../../icons';
66
import { useTheme } from '../../theme';
@@ -14,6 +14,7 @@ interface SearchBarProps {
1414
placeholder?: string;
1515
sx?: SxProps<Theme>;
1616
endAdornment?: React.ReactNode;
17+
debounceTime?: number;
1718
}
1819

1920
/**
@@ -26,6 +27,7 @@ interface SearchBarProps {
2627
* @param {string} [props.placeholder] - The placeholder text for the search input.
2728
* @param {Object} [props.sx] - The style object for the search input.
2829
* @param {React.ReactNode} [props.endAdornment] - The element to display at the end of the search input.
30+
* @param {number} [props.debounceTime] - The debounce time for the input change handler.
2931
*
3032
* @returns {JSX.Element} The rendered StyledSearchBar component.
3133
*/
@@ -35,25 +37,40 @@ function StyledSearchBar({
3537
label,
3638
sx,
3739
placeholder,
38-
endAdornment
40+
endAdornment,
41+
debounceTime = 300
3942
}: SearchBarProps): JSX.Element {
4043
const theme = useTheme();
41-
const [inputValue, setInputValue] = useState(value);
44+
const [inputValue, setInputValue] = useState(value ?? '');
4245

43-
const debouncedOnChange = useCallback(
44-
(event: React.ChangeEvent<HTMLInputElement>) => {
45-
debounce(() => {
46-
if (onChange) {
47-
onChange(event);
48-
}
49-
}, 300)();
50-
},
51-
[onChange]
52-
);
46+
useEffect(() => {
47+
if (value !== undefined && value !== inputValue) {
48+
setInputValue(value);
49+
}
50+
// eslint-disable-next-line react-hooks/exhaustive-deps
51+
}, [value]);
52+
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>;
60+
61+
onChange(syntheticEvent);
62+
}
63+
}, debounceTime);
64+
65+
handler(inputValue);
66+
67+
return () => {
68+
handler.cancel();
69+
};
70+
}, [inputValue, onChange, debounceTime]);
5371

5472
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
5573
setInputValue(event.target.value);
56-
debouncedOnChange(event);
5774
};
5875

5976
return (

0 commit comments

Comments
 (0)