-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG]: incorrect behavior on debonuce of onSearch
in useSelect
#6096
Comments
Hey @Dominic-Preap, I've tested the behavior in our test environment and also used your code in a project but could not reproduce the issue. Looks like |
Let me add testing repo. |
@aliemir Here is the test repo. I think I know the problem is. We use // blog-posts/create.tsx
// Page
<Controller
control={control}
name="category"
render={({ field: { onChange, value }, fieldState: { error } }) => (
<CategorySearch
error={error?.message}
onChange={onChange}
value={value}
/>
)}
const CategorySearch: React.FC<Props> = ({ onChange, value, error }) => {
const { onSearch, queryResult } = useSelect({
resource: "categories",
debounce: 1500,
searchField: "title",
});
// ! Debounce working okay <---- SWITCH FUNCTION HERE
const handleChange = useCallback((value: string) => {
onChange?.(value);
onSearch(value);
}, []);
// ! Debounce run fetch multiple <---- SWITCH FUNCTION HERE
const handleChange = (value: string) => {
onChange?.(value);
onSearch(value);
};
return (
<label>
<span style={{ marginRight: "8px" }}>Category</span>
<input
onChange={(e) => handleChange(e.currentTarget.value)}
value={value}
/>
<span style={{ color: "red" }}>{error}</span>
<ul>
{queryResult.data?.data.map((x) => (
<li key={x.title}>{x.title}</li>
))}
</ul>
</label>
);
}; |
Hey @Dominic-Preap, just checked your repro and the code you've provided. Confirming the issue about the debounced callback of
This prop also causes re-renders if it's inlined. We can store it in a ref like this: /**
* To avoid any changes in the `onSearch` callback,
* We're storing `onSearchFromProp` in a ref and accessing it in the `onSearch` callback.
*/
const onSearchFromPropRef = useRef(onSearchFromProp);
useEffect(() => {
onSearchFromPropRef.current = onSearchFromProp;
}, [onSearchFromProp]); We should move Current: refine/packages/core/src/hooks/useSelect/index.ts Lines 338 to 356 in 49d65bf
Wrapping it with const onSearch = useMemo(() => {
return debounce((value: string) => {
if (onSearchFromPropRef.current) {
setSearch(onSearchFromPropRef.current(value));
return;
}
if (!value) {
setSearch([]);
return;
}
setSearch([
{
field: searchField,
operator: "contains",
value,
},
]);
}, debounceValue);
}, [searchField, debounceValue]); Then we can just update the return statement: return {
queryResult,
defaultValueQueryResult,
options: combinedOptions,
- onSearch: debounce(onSearch, debounceValue),
+ onSearch,
overtime: { elapsedTime },
}; Let me know if you can work on this and open up a PR 🙏 |
Thanks for your explanation and sure I'll check it out and make a PR. |
Describe the bug
When use
onSearch
inuseSelect
, we see that fetch requests called repeatedly after delay ondebonuce
value. Video demo is below.refine.mp4
Steps To Reproduce
Sample code:
Expected behavior
It should delay then executed
onSearch
once or throttlingonSearch
function. After checking in package it seems to usedebounce
from loadash. I suggest using use-debounce or any libs that are similar.Packages
Additional Context
This will lead to multiple requests to the server if not handle properly.
The text was updated successfully, but these errors were encountered: