@@ -182,41 +182,24 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
182
182
} ;
183
183
184
184
// ========================== Get Next Matching Node ==========================
185
+ const availableNodesRef = React . useRef < EventDataNode < any > [ ] > ( [ ] ) ;
186
+
185
187
const getNextMatchingNode = (
186
- nodes : EventDataNode < any > [ ] ,
187
188
currentKey : Key | null ,
188
189
direction : 'next' | 'prev' = 'next' ,
189
190
) : EventDataNode < any > | null => {
190
- const availableNodes : EventDataNode < any > [ ] = [ ] ;
191
-
192
- const collectNodes = ( nodeList : EventDataNode < any > [ ] ) => {
193
- nodeList . forEach ( node => {
194
- if ( ! node . disabled && node . selectable !== false ) {
195
- // only collect selected nodes
196
- if ( displayValues ?. some ( v => v . value === node [ fieldNames . value ] ) ) {
197
- availableNodes . push ( node ) ;
198
- }
199
- }
200
- if ( node [ fieldNames . children ] ) {
201
- collectNodes ( node [ fieldNames . children ] ) ;
202
- }
203
- } ) ;
204
- } ;
205
-
206
- collectNodes ( nodes ) ;
191
+ const availableNodes = availableNodesRef . current ;
207
192
208
193
if ( availableNodes . length === 0 ) {
209
194
return null ;
210
195
}
211
196
212
- // if no current selected node, return first available node
213
197
if ( ! currentKey ) {
214
198
return availableNodes [ 0 ] ;
215
199
}
216
200
217
201
const currentIndex = availableNodes . findIndex ( node => node [ fieldNames . value ] === currentKey ) ;
218
202
219
- // if current node is not in available nodes list, return first node
220
203
if ( currentIndex === - 1 ) {
221
204
return availableNodes [ 0 ] ;
222
205
}
@@ -229,6 +212,27 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
229
212
return availableNodes [ nextIndex ] ;
230
213
} ;
231
214
215
+ React . useEffect ( ( ) => {
216
+ const nodes : EventDataNode < any > [ ] = [ ] ;
217
+ const selectedValueSet = new Set ( displayValues ?. map ( v => v . value ) ) ;
218
+
219
+ const collectNodes = ( nodeList : EventDataNode < any > [ ] ) => {
220
+ nodeList . forEach ( node => {
221
+ if ( ! node . disabled && node . selectable !== false ) {
222
+ if ( selectedValueSet . has ( node [ fieldNames . value ] ) ) {
223
+ nodes . push ( node ) ;
224
+ }
225
+ }
226
+ if ( node [ fieldNames . children ] ) {
227
+ collectNodes ( node [ fieldNames . children ] ) ;
228
+ }
229
+ } ) ;
230
+ } ;
231
+
232
+ collectNodes ( memoTreeData ) ;
233
+ availableNodesRef . current = nodes ;
234
+ } , [ displayValues , memoTreeData ] ) ;
235
+
232
236
// ========================== Active ==========================
233
237
const [ activeKey , setActiveKey ] = React . useState < Key > ( null ) ;
234
238
const activeEntity = keyEntities [ activeKey as SafeKey ] ;
@@ -268,10 +272,9 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
268
272
if ( isOverMaxCount ) {
269
273
event . preventDefault ( ) ;
270
274
const direction = which === KeyCode . UP || which === KeyCode . LEFT ? 'prev' : 'next' ;
271
- const nextNode = getNextMatchingNode ( memoTreeData , activeKey , direction ) ;
275
+ const nextNode = getNextMatchingNode ( activeKey , direction ) ;
272
276
if ( nextNode ) {
273
277
setActiveKey ( nextNode [ fieldNames . value ] ) ;
274
- // ensure scroll to visible area
275
278
treeRef . current ?. scrollTo ( { key : nextNode [ fieldNames . value ] } ) ;
276
279
}
277
280
} else {
@@ -315,7 +318,7 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
315
318
return ;
316
319
}
317
320
318
- const nextNode = getNextMatchingNode ( memoTreeData , key ) ;
321
+ const nextNode = getNextMatchingNode ( key ) ;
319
322
if ( nextNode ) {
320
323
setActiveKey ( nextNode [ fieldNames . value ] ) ;
321
324
}
0 commit comments