[DevTools] fix: keep search query in a local sync state (#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.
This commit is contained in:
Ruslan Lesiutin
2025-09-10 18:38:47 +01:00
committed by GitHub
parent 886b3d36d7
commit e2ba45bb39
@@ -8,22 +8,34 @@
*/
import * as React from 'react';
import {useContext} from 'react';
import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
import {useState, useContext, useCallback} from 'react';
import SearchInput from '../SearchInput';
import SearchInput from 'react-devtools-shared/src/devtools/views/SearchInput';
import {
TreeDispatcherContext,
TreeStateContext,
} from 'react-devtools-shared/src/devtools/views/Components/TreeContext';
type Props = {};
export default function ComponentSearchInput(): React.Node {
const [localSearchQuery, setLocalSearchQuery] = useState('');
const {searchIndex, searchResults} = useContext(TreeStateContext);
const transitionDispatch = useContext(TreeDispatcherContext);
export default function ComponentSearchInput(props: Props): React.Node {
const {searchIndex, searchResults, searchText} = useContext(TreeStateContext);
const dispatch = useContext(TreeDispatcherContext);
const search = (text: string) =>
dispatch({type: 'SET_SEARCH_TEXT', payload: text});
const goToNextResult = () => dispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'});
const goToPreviousResult = () =>
dispatch({type: 'GO_TO_PREVIOUS_SEARCH_RESULT'});
const search = useCallback(
(text: string) => {
setLocalSearchQuery(text);
transitionDispatch({type: 'SET_SEARCH_TEXT', payload: text});
},
[setLocalSearchQuery, transitionDispatch],
);
const goToNextResult = useCallback(
() => transitionDispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'}),
[transitionDispatch],
);
const goToPreviousResult = useCallback(
() => transitionDispatch({type: 'GO_TO_PREVIOUS_SEARCH_RESULT'}),
[transitionDispatch],
);
return (
<SearchInput
@@ -33,7 +45,7 @@ export default function ComponentSearchInput(props: Props): React.Node {
search={search}
searchIndex={searchIndex}
searchResultsCount={searchResults.length}
searchText={searchText}
searchText={localSearchQuery}
testName="ComponentSearchInput"
/>
);