Skip to content

Commit

Permalink
perf: use cache to improve navigation performance
Browse files Browse the repository at this point in the history
  • Loading branch information
aojunhao123 committed Nov 21, 2024
1 parent 06ee328 commit ff9f216
Showing 1 changed file with 26 additions and 23 deletions.
49 changes: 26 additions & 23 deletions src/OptionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,41 +182,24 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
};

// ========================== Get Next Matching Node ==========================
const availableNodesRef = React.useRef<EventDataNode<any>[]>([]);

const getNextMatchingNode = (
nodes: EventDataNode<any>[],
currentKey: Key | null,
direction: 'next' | 'prev' = 'next',
): EventDataNode<any> | null => {
const availableNodes: EventDataNode<any>[] = [];

const collectNodes = (nodeList: EventDataNode<any>[]) => {
nodeList.forEach(node => {
if (!node.disabled && node.selectable !== false) {
// only collect selected nodes
if (displayValues?.some(v => v.value === node[fieldNames.value])) {
availableNodes.push(node);
}
}
if (node[fieldNames.children]) {
collectNodes(node[fieldNames.children]);
}
});
};

collectNodes(nodes);
const availableNodes = availableNodesRef.current;

if (availableNodes.length === 0) {
return null;
}

// if no current selected node, return first available node
if (!currentKey) {
return availableNodes[0];
}

const currentIndex = availableNodes.findIndex(node => node[fieldNames.value] === currentKey);

// if current node is not in available nodes list, return first node
if (currentIndex === -1) {
return availableNodes[0];
}
Expand All @@ -229,6 +212,27 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
return availableNodes[nextIndex];
};

React.useEffect(() => {
const nodes: EventDataNode<any>[] = [];
const selectedValueSet = new Set(displayValues?.map(v => v.value));

const collectNodes = (nodeList: EventDataNode<any>[]) => {
nodeList.forEach(node => {
if (!node.disabled && node.selectable !== false) {
if (selectedValueSet.has(node[fieldNames.value])) {
nodes.push(node);
}
}
if (node[fieldNames.children]) {
collectNodes(node[fieldNames.children]);
}
});
};

collectNodes(memoTreeData);
availableNodesRef.current = nodes;
}, [displayValues, memoTreeData]);

// ========================== Active ==========================
const [activeKey, setActiveKey] = React.useState<Key>(null);
const activeEntity = keyEntities[activeKey as SafeKey];
Expand Down Expand Up @@ -268,10 +272,9 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
if (isOverMaxCount) {
event.preventDefault();
const direction = which === KeyCode.UP || which === KeyCode.LEFT ? 'prev' : 'next';
const nextNode = getNextMatchingNode(memoTreeData, activeKey, direction);
const nextNode = getNextMatchingNode(activeKey, direction);
if (nextNode) {
setActiveKey(nextNode[fieldNames.value]);
// ensure scroll to visible area
treeRef.current?.scrollTo({ key: nextNode[fieldNames.value] });
}
} else {
Expand Down Expand Up @@ -315,7 +318,7 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
return;
}

const nextNode = getNextMatchingNode(memoTreeData, key);
const nextNode = getNextMatchingNode(key);
if (nextNode) {
setActiveKey(nextNode[fieldNames.value]);
}
Expand Down

0 comments on commit ff9f216

Please sign in to comment.