Skip to content

Commit 0e494d4

Browse files
feat: improve tree item reuse for React
1 parent 649216a commit 0e494d4

File tree

2 files changed

+17
-15
lines changed

2 files changed

+17
-15
lines changed

src/webview/SearchSidebar/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const SearchSidebar = () => {
1313
)
1414
const {
1515
queryInFlight,
16-
searchResult,
16+
searchCount,
1717
groupedByFileSearchResult,
1818
refreshSearchResult,
1919
searching
@@ -29,7 +29,7 @@ export const SearchSidebar = () => {
2929
/>
3030
<SearchProviderMessage
3131
pattern={queryInFlight}
32-
resultCount={searchResult.length}
32+
resultCount={searchCount}
3333
fileCount={groupedByFileSearchResult.length}
3434
/>
3535
<SearchResultList matches={groupedByFileSearchResult} />

src/webview/hooks/useSearch.tsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import type { DisplayResult } from '../postMessage'
22
import { childPort } from '../postMessage'
3-
import {
4-
useCallback,
5-
useDeferredValue,
6-
useMemo,
7-
useSyncExternalStore
8-
} from 'react'
3+
import { useCallback, useDeferredValue, useSyncExternalStore } from 'react'
94
import { useDebounce } from 'react-use'
105

116
// id should not overflow, the MOD is large enough
@@ -14,16 +9,16 @@ const MOD = 1e9 + 7
149

1510
// maintain the latest search task id and callback
1611
let id = 0
17-
let searchResult: DisplayResult[] = []
12+
let grouped = [] as [string, DisplayResult[]][]
1813
let queryInFlight = ''
1914
let searching = true
2015
let notify = () => {}
2116

2217
function postSearch(inputValue: string) {
2318
id = (id + 1) % MOD
2419
childPort.postMessage('search', { id, inputValue })
25-
searchResult = []
2620
searching = true
21+
grouped = []
2722
notify()
2823
}
2924

@@ -32,7 +27,7 @@ childPort.onMessage('searchResultStreaming', event => {
3227
return
3328
}
3429
queryInFlight = event.inputValue
35-
searchResult = searchResult.concat(event.searchResult)
30+
grouped = merge(groupBy(event.searchResult))
3631
notify()
3732
})
3833

@@ -56,6 +51,16 @@ function groupBy(matches: DisplayResult[]) {
5651
return groups
5752
}
5853

54+
function merge(newEntries: Map<string, DisplayResult[]>) {
55+
// first, clone the old map for react
56+
let temp = new Map(grouped)
57+
for (const [file, newList] of newEntries) {
58+
const existing = temp.get(file) || []
59+
temp.set(file, existing.concat(newList))
60+
}
61+
return [...temp.entries()]
62+
}
63+
5964
// version is for react to update view
6065
let version = 114514
6166
function subscribe(onChange: () => void): () => void {
@@ -81,9 +86,6 @@ export const useSearchResult = (inputValue: string) => {
8186
postSearch(inputValue)
8287
}, [inputValue])
8388

84-
const grouped = useMemo(() => {
85-
return [...groupBy(searchResult).entries()]
86-
}, [searchResult])
8789
// rendering tree is too expensive, useDeferredValue
8890
const groupedByFileSearchResult = useDeferredValue(grouped)
8991

@@ -92,8 +94,8 @@ export const useSearchResult = (inputValue: string) => {
9294
return {
9395
queryInFlight,
9496
searching,
95-
searchResult,
9697
groupedByFileSearchResult,
98+
searchCount: grouped.reduce((a, l) => a + l[1].length, 0),
9799
refreshSearchResult
98100
}
99101
}

0 commit comments

Comments
 (0)