async-tree-select.tsx
Overview
async-tree-select.tsx is a React functional component that provides an asynchronously loaded tree selection UI element using the Ant Design (antd) TreeSelect component. It enables users to select folders from a hierarchical file structure, where the folder data is fetched dynamically on demand (lazy-loading). This component integrates with a file management system by fetching folder data via a custom hook and renders it in a tree-select dropdown with smooth user experience and internationalization support.
Detailed Explanation
Component: AsyncTreeSelect
Purpose
AsyncTreeSelect renders a dropdown tree selector that loads folder nodes asynchronously from a backend or data source. It is designed specifically for selecting folders from a file management hierarchy.
Props
Prop Name | Type | Description |
|---|---|---|
| [string \ | undefined](/projects/311/74002) |
| [(value: string) => void \ | undefined](/projects/311/71659) |
Internal State
State Name | Type | Description |
|---|---|---|
| The flattened array of tree nodes representing folders, formatted for Ant Design's |
Hooks and Dependencies
useTranslationfromreact-i18nextfor internationalized placeholder text.useFetchPureFileList(custom hook) to fetch folder data asynchronously.React hooks:
useState,useCallback,useEffect.
Functions and Methods
onLoadData
const onLoadData: TreeSelectProps['loadData'] = useCallback(
async ({ id }) => {
const ret = await fetchList(id);
if (ret.code === 0) {
setTreeData((tree) => {
return tree.concat(
ret.data.files
.filter((x: IFile) => x.type === 'folder')
.map((x: IFile) => ({
id: x.id,
pId: x.parent_id,
value: x.id,
title: x.name,
isLeaf:
typeof x.has_child_folder === 'boolean'
? !x.has_child_folder
: false,
})),
);
});
}
},
[fetchList],
);
Purpose: Loads child folder nodes for a given folder ID asynchronously.
Parameters:
Destructured object with
id: string— the ID of the folder node to load children for.
Returns:
Promise<void>(implicitly, as it’s an async function).Functionality:
Calls
fetchList(id)from the file manager hook to retrieve folder list under the folder with the given ID.On successful fetch (
ret.code === 0), it filters the files to include only those of type'folder'.Extracts relevant properties (
id,parent_id,name,has_child_folder) and maps them to the format expected by Ant Design'sTreeSelectintreeDataSimpleMode.Updates the
treeDatastate by concatenating the new nodes.
Usage: Passed as the
loadDataprop to the Ant DesignTreeSelectcomponent to enable lazy loading of tree nodes when a node is expanded.
handleChange
const handleChange = (newValue: string) => {
onChange?.(newValue);
};
Purpose: Wrapper handler that calls the optional
onChangeprop with the new selected value.Parameters:
newValue: string— the newly selected folder ID.
Returns: void.
Usage: Used as the
onChangehandler for theTreeSelectcomponent.
React Lifecycle
useEffectwith dependency[onLoadData]triggers initial loading of root-level folders by callingonLoadData({ id: '' })once on mount.
Rendered Output
Renders an antd TreeSelect with these key props:
treeDataSimpleMode: Enables simplified tree data format (flat list withidandpId).style: Full width.value: Controlled selected folder ID.dropdownStyle: Max height with scroll.placeholder: Localized "please select" message.onChange: Controlled handler that triggersonChangeprop.loadData: Async loading function for expanding nodes.treeData: The array of folder nodes.
Implementation Details and Algorithms
Lazy Loading Algorithm: When a user expands a tree node, the
loadDatafunction (onLoadData) fetches child folders asynchronously from the backend. This avoids loading the entire file tree at once, improving performance and responsiveness for large folder structures.Data Transformation: Fetched folder data is filtered and transformed to match Ant Design's
TreeSelectcomponent'streeDataSimpleModeformat, which requires flat arrays withid,pId(parent ID), andtitle.Leaf Node Determination: The
isLeafproperty is computed based on thehas_child_folderboolean from the fetched data, indicating whether the folder has children (leaf or non-leaf node).Internationalization: The placeholder text uses
react-i18nextfor multilingual support.
Integration and Interaction
File Manager Integration: Uses the custom hook
useFetchPureFileListto fetch folder lists from the backend or database. This hook likely interacts with APIs or state management related to file management.UI Framework Dependency: Relies on Ant Design's
TreeSelectcomponent to provide the UI and tree selection logic.Localization System: Integrates with
react-i18nextfor translating UI text.Parent Components: This component expects
valueandonChangeprops to be managed by a parent component controlling selected folder state.
Usage Example
import AsyncTreeSelect from './async-tree-select';
const ParentComponent = () => {
const [selectedFolder, setSelectedFolder] = useState<string | undefined>();
return (
<AsyncTreeSelect
value={selectedFolder}
onChange={(val) => setSelectedFolder(val)}
/>
);
};
Mermaid Component Diagram
componentDiagram
component AsyncTreeSelect {
+value?: string
+onChange?: (value: string) => void
-treeData: Array<TreeNode>
-onLoadData({id}): Promise<void>
-handleChange(newValue: string): void
}
component useFetchPureFileList {
+fetchList(id: string): Promise<FileListResponse>
}
component TreeSelect {
+treeDataSimpleMode: boolean
+value: string
+onChange: (value: string) => void
+loadData: (node) => Promise<void>
+treeData: Array<TreeNode>
}
component useTranslation {
+t(key: string): string
}
AsyncTreeSelect --> useFetchPureFileList : fetchList()
AsyncTreeSelect --> useTranslation : t()
AsyncTreeSelect --> TreeSelect : renders
Summary
async-tree-select.tsx encapsulates an asynchronously loaded folder tree selector that efficiently fetches folder data on demand, integrates smoothly with a file management backend, and provides a user-friendly, localized tree selection UI using Ant Design components. Its architecture and lazy loading strategy make it suitable for large and dynamic folder structures.