@@ -3,7 +3,7 @@ import {InfoTableProps} from './Prompts/InfoTable.js'
33import { TextInput } from './TextInput.js'
44import { InfoMessageProps } from './Prompts/InfoMessage.js'
55import { Message , PromptLayout } from './Prompts/PromptLayout.js'
6- import { debounce } from '../../../../public/common/function.js'
6+ import { throttle } from '../../../../public/common/function.js'
77import { AbortSignal } from '../../../../public/node/abort.js'
88import usePrompt , { PromptState } from '../hooks/use-prompt.js'
99import React , { ReactElement , useCallback , useEffect , useRef , useState } from 'react'
@@ -84,40 +84,40 @@ function AutocompletePrompt<T>({
8484 const searchTermRef = useRef ( '' )
8585 searchTermRef . current = searchTerm
8686
87- // disable exhaustive-deps because we want to memoize the debounce function itself
88- // eslint-disable-next-line react-hooks/exhaustive-deps
89- const debounceSearch = useCallback (
90- debounce (
91- ( term : string ) => {
92- setLoadingWhenSlow . current = setTimeout ( ( ) => {
93- setPromptState ( PromptState . Loading )
94- } , 100 )
95- paginatedSearch ( term )
96- . then ( ( result ) => {
97- // while we were waiting for the promise to resolve, the user
98- // has emptied the search term, so we want to show the default
99- // choices instead
100- if ( searchTermRef . current . length === 0 ) {
101- setSearchResults ( choices )
102- setHasMorePages ( initialHasMorePages )
103- } else {
104- setSearchResults ( result . data )
105- setHasMorePages ( result . meta ?. hasNextPage ?? false )
106- }
87+ // useMemo ensures debounceSearch is not recreated on every render
88+ const debounceSearch = React . useMemo (
89+ ( ) =>
90+ throttle (
91+ ( term : string ) => {
92+ setLoadingWhenSlow . current = setTimeout ( ( ) => {
93+ setPromptState ( PromptState . Loading )
94+ } , 100 )
95+ paginatedSearch ( term )
96+ . then ( ( result ) => {
97+ // while we were waiting for the promise to resolve, the user
98+ // has emptied the search term, so we want to show the default
99+ // choices instead
100+ if ( searchTermRef . current . length === 0 ) {
101+ setSearchResults ( choices )
102+ setHasMorePages ( initialHasMorePages )
103+ } else {
104+ setSearchResults ( result . data )
105+ setHasMorePages ( result . meta ?. hasNextPage ?? false )
106+ }
107107
108- setPromptState ( PromptState . Idle )
109- } )
110- . catch ( ( ) => {
111- setPromptState ( PromptState . Error )
112- } )
113- . finally ( ( ) => {
114- clearTimeout ( setLoadingWhenSlow . current )
115- } )
116- } ,
117- 300 ,
118- { leading : true } ,
119- ) ,
120- [ initialHasMorePages , choices , paginatedSearch , searchResults ] ,
108+ setPromptState ( PromptState . Idle )
109+ } )
110+ . catch ( ( ) => {
111+ setPromptState ( PromptState . Error )
112+ } )
113+ . finally ( ( ) => {
114+ clearTimeout ( setLoadingWhenSlow . current )
115+ } )
116+ } ,
117+ 400 ,
118+ { leading : true , trailing : true } ,
119+ ) ,
120+ [ paginatedSearch ] ,
121121 )
122122
123123 return (
0 commit comments