Skip to content

Commit 2caf7a7

Browse files
authored
fix: remove just-debounce-it (coder#9707)
* fix: Switch UserAutocomplete to useDebouncedFunction * fix: switch UserOrGroupAutocomplete to useDebouncedFunction * chore: remove just-debounce-it dependency * docs: Clean up comments
1 parent a2aff1f commit 2caf7a7

File tree

4 files changed

+26
-20
lines changed

4 files changed

+26
-20
lines changed

site/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@
158158
"jest-runner-eslint": "2.1.0",
159159
"jest-websocket-mock": "2.5.0",
160160
"jest_workaround": "0.1.14",
161-
"just-debounce-it": "3.2.0",
162161
"msw": "1.3.0",
163162
"prettier": "3.0.0",
164163
"protobufjs": "7.2.4",

site/pnpm-lock.yaml

Lines changed: 0 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/src/components/UserAutocomplete/UserAutocomplete.tsx

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,17 @@ import { useMachine } from "@xstate/react";
66
import { User } from "api/typesGenerated";
77
import { Avatar } from "components/Avatar/Avatar";
88
import { AvatarData } from "components/AvatarData/AvatarData";
9-
import debounce from "just-debounce-it";
10-
import { ChangeEvent, ComponentProps, FC, useEffect, useState } from "react";
9+
import {
10+
ChangeEvent,
11+
ComponentProps,
12+
FC,
13+
useEffect,
14+
useRef,
15+
useState,
16+
} from "react";
1117
import { searchUserMachine } from "xServices/users/searchUserXService";
1218
import Box from "@mui/material/Box";
19+
import { useDebouncedFunction } from "hooks/debounce";
1320

1421
export type UserAutocompleteProps = {
1522
value: User | null;
@@ -31,16 +38,23 @@ export const UserAutocomplete: FC<UserAutocompleteProps> = ({
3138
const [searchState, sendSearch] = useMachine(searchUserMachine);
3239
const { searchResults } = searchState.context;
3340

34-
// seed list of options on the first page load if a user pases in a value
35-
// since some organizations have long lists of users, we do not load all options on page load.
41+
// Seed list of options on the first page load if a user passes in a value.
42+
// Since some organizations have long lists of users, we do not want to load
43+
// all options on page load.
44+
const onMountRef = useRef(value);
3645
useEffect(() => {
37-
if (value) {
38-
sendSearch("SEARCH", { query: value.email });
46+
const mountValue = onMountRef.current;
47+
if (mountValue) {
48+
sendSearch("SEARCH", { query: mountValue.email });
3949
}
40-
// eslint-disable-next-line react-hooks/exhaustive-deps -- TODO look into this
41-
}, []);
4250

43-
const handleFilterChange = debounce(
51+
// This isn't in XState's docs, but its source code guarantees that the
52+
// memory reference of sendSearch will stay stable across renders. This
53+
// useEffect call will behave like an on-mount effect and will not ever need
54+
// to resynchronize
55+
}, [sendSearch]);
56+
57+
const { debounced: debouncedOnChange } = useDebouncedFunction(
4458
(event: ChangeEvent<HTMLInputElement>) => {
4559
sendSearch("SEARCH", { query: event.target.value });
4660
},
@@ -93,7 +107,7 @@ export const UserAutocomplete: FC<UserAutocompleteProps> = ({
93107
className={styles.textField}
94108
InputProps={{
95109
...params.InputProps,
96-
onChange: handleFilterChange,
110+
onChange: debouncedOnChange,
97111
startAdornment: value && (
98112
<Avatar size="sm" src={value.avatar_url}>
99113
{value.username}

site/src/components/UserOrGroupAutocomplete/UserOrGroupAutocomplete.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import Autocomplete from "@mui/material/Autocomplete";
55
import { useMachine } from "@xstate/react";
66
import { Group, User } from "api/typesGenerated";
77
import { AvatarData } from "components/AvatarData/AvatarData";
8-
import debounce from "just-debounce-it";
98
import { ChangeEvent, useState } from "react";
109
import { getGroupSubtitle } from "utils/groups";
1110
import { searchUsersAndGroupsMachine } from "xServices/template/searchUsersAndGroupsXService";
1211
import Box from "@mui/material/Box";
12+
import { useDebouncedFunction } from "hooks/debounce";
1313

1414
export type UserOrGroupAutocompleteValue = User | Group | null;
1515

@@ -44,7 +44,7 @@ export const UserOrGroupAutocomplete: React.FC<
4444
return !excludeIds.includes(result.id);
4545
});
4646

47-
const handleFilterChange = debounce(
47+
const { debounced: handleFilterChange } = useDebouncedFunction(
4848
(event: ChangeEvent<HTMLInputElement>) => {
4949
sendSearch("SEARCH", { query: event.target.value });
5050
},

0 commit comments

Comments
 (0)