Skip to content

Commit e2ba45b

Browse files
authored
[DevTools] fix: keep search query in a local sync state (facebook#34423)
When the search query changes, we kick off a transition that updates the search query in a reducer for TreeContext. The search input is also using this value for an `input` HTML element. For a larger applications, sometimes there is a noticeable delay in displaying the updated search query. This changes the approach to also keep a local synchronous state that is being updated on a change callback.
1 parent 886b3d3 commit e2ba45b

File tree

1 file changed

+26
-14
lines changed

1 file changed

+26
-14
lines changed

packages/react-devtools-shared/src/devtools/views/Components/ComponentSearchInput.js

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,34 @@
88
*/
99

1010
import * as React from 'react';
11-
import {useContext} from 'react';
12-
import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
11+
import {useState, useContext, useCallback} from 'react';
1312

14-
import SearchInput from '../SearchInput';
13+
import SearchInput from 'react-devtools-shared/src/devtools/views/SearchInput';
14+
import {
15+
TreeDispatcherContext,
16+
TreeStateContext,
17+
} from 'react-devtools-shared/src/devtools/views/Components/TreeContext';
1518

16-
type Props = {};
19+
export default function ComponentSearchInput(): React.Node {
20+
const [localSearchQuery, setLocalSearchQuery] = useState('');
21+
const {searchIndex, searchResults} = useContext(TreeStateContext);
22+
const transitionDispatch = useContext(TreeDispatcherContext);
1723

18-
export default function ComponentSearchInput(props: Props): React.Node {
19-
const {searchIndex, searchResults, searchText} = useContext(TreeStateContext);
20-
const dispatch = useContext(TreeDispatcherContext);
21-
22-
const search = (text: string) =>
23-
dispatch({type: 'SET_SEARCH_TEXT', payload: text});
24-
const goToNextResult = () => dispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'});
25-
const goToPreviousResult = () =>
26-
dispatch({type: 'GO_TO_PREVIOUS_SEARCH_RESULT'});
24+
const search = useCallback(
25+
(text: string) => {
26+
setLocalSearchQuery(text);
27+
transitionDispatch({type: 'SET_SEARCH_TEXT', payload: text});
28+
},
29+
[setLocalSearchQuery, transitionDispatch],
30+
);
31+
const goToNextResult = useCallback(
32+
() => transitionDispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'}),
33+
[transitionDispatch],
34+
);
35+
const goToPreviousResult = useCallback(
36+
() => transitionDispatch({type: 'GO_TO_PREVIOUS_SEARCH_RESULT'}),
37+
[transitionDispatch],
38+
);
2739

2840
return (
2941
<SearchInput
@@ -33,7 +45,7 @@ export default function ComponentSearchInput(props: Props): React.Node {
3345
search={search}
3446
searchIndex={searchIndex}
3547
searchResultsCount={searchResults.length}
36-
searchText={searchText}
48+
searchText={localSearchQuery}
3749
testName="ComponentSearchInput"
3850
/>
3951
);

0 commit comments

Comments
 (0)