@@ -7,7 +7,16 @@ import {
77 isInterfaceType ,
88 isObjectType ,
99} from 'graphql' ;
10- import { FocusEventHandler , useEffect , useRef , useState } from 'react' ;
10+ import {
11+ FocusEventHandler ,
12+ // eslint-disable-next-line @typescript-eslint/no-restricted-imports
13+ useCallback ,
14+ useEffect ,
15+ // eslint-disable-next-line @typescript-eslint/no-restricted-imports
16+ useMemo ,
17+ useRef ,
18+ useState ,
19+ } from 'react' ;
1120import { Combobox } from '@headlessui/react' ;
1221import { MagnifyingGlassIcon } from '../../icons' ;
1322import { useSchemaContext } from '../../schema' ;
@@ -20,6 +29,7 @@ import { renderType } from './utils';
2029import { isMacOs } from '../../utility/is-macos' ;
2130
2231export function Search ( ) {
32+ 'use no memo' ; // TODO: add test https://github.com/graphql/graphiql/issues/3842
2333 const { explorerNavStack, push } = useExplorerContext ( {
2434 nonNull : true ,
2535 caller : Search ,
@@ -29,10 +39,13 @@ export function Search() {
2939 const getSearchResults = useSearchResults ( ) ;
3040 const [ searchValue , setSearchValue ] = useState ( '' ) ;
3141 const [ results , setResults ] = useState ( getSearchResults ( searchValue ) ) ;
32- const [ isFocused , setIsFocused ] = useState ( false ) ;
33- const debouncedGetSearchResults = debounce ( 200 , ( search : string ) => {
34- setResults ( getSearchResults ( search ) ) ;
35- } ) ;
42+ const debouncedGetSearchResults = useMemo (
43+ ( ) =>
44+ debounce ( 200 , ( search : string ) => {
45+ setResults ( getSearchResults ( search ) ) ;
46+ } ) ,
47+ [ getSearchResults ] ,
48+ ) ;
3649 useEffect ( ( ) => {
3750 debouncedGetSearchResults ( searchValue ) ;
3851 } , [ debouncedGetSearchResults , searchValue ] ) ;
@@ -50,16 +63,20 @@ export function Search() {
5063
5164 const navItem = explorerNavStack . at ( - 1 ) ! ;
5265
53- const onSelect = ( def : TypeMatch | FieldMatch ) => {
54- push (
55- 'field' in def
56- ? { name : def . field . name , def : def . field }
57- : { name : def . type . name , def : def . type } ,
58- ) ;
59- } ;
60- const handleFocus : FocusEventHandler = e => {
61- setIsFocused ( e . type === 'focus' ) ;
62- } ;
66+ const onSelect = useCallback (
67+ ( def : TypeMatch | FieldMatch ) => {
68+ push (
69+ 'field' in def
70+ ? { name : def . field . name , def : def . field }
71+ : { name : def . type . name , def : def . type } ,
72+ ) ;
73+ } ,
74+ [ push ] ,
75+ ) ;
76+ const isFocused = useRef ( false ) ;
77+ const handleFocus : FocusEventHandler = useCallback ( e => {
78+ isFocused . current = e . type === 'focus' ;
79+ } , [ ] ) ;
6380
6481 const shouldSearchBoxAppear =
6582 explorerNavStack . length === 1 ||
@@ -98,7 +115,8 @@ export function Search() {
98115 </ div >
99116
100117 { /* display on focus */ }
101- { isFocused && (
118+ { /* eslint-disable-next-line react-compiler/react-compiler */ }
119+ { isFocused . current && (
102120 < Combobox . Options data-cy = "doc-explorer-list" >
103121 { results . within . length +
104122 results . types . length +
0 commit comments