You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助开发支持任意层级文件夹创建的Component(含文件夹与子文件夹)

实现无限层级文件夹组件(支持任意层级创建)

核心思路

用递归数据结构存储文件夹层级,通过递归组件渲染嵌套结构,同时维护当前选中的文件夹ID,点击Add按钮时在选中节点下插入新文件夹。


1. 定义数据结构

每个文件夹节点包含唯一ID、名称、子节点数组,支持无限嵌套:

// 初始文件夹数据示例
const initialFolderData = [
  {
    id: 'root-1',
    name: '项目文档',
    children: [
      { id: 'sub-1', name: '需求分析', children: [] },
      { id: 'sub-2', name: '设计稿', children: [
          { id: 'sub-2-1', name: '移动端', children: [] }
        ]
      }
    ]
  },
  { id: 'root-2', name: '开发资源', children: [] }
];

2. React组件实现(示例)

父组件(主容器)

负责维护全局状态(文件夹数据、选中ID),以及添加文件夹的核心逻辑:

import { useState } from 'react';
import FolderNode from './FolderNode';

export default function FolderTree() {
  const [folders, setFolders] = useState(initialFolderData);
  const [selectedFolderId, setSelectedFolderId] = useState(null);

  // 递归查找目标节点并添加子文件夹
  const addSubFolder = (nodes, targetId) => {
    return nodes.map(node => {
      if (node.id === targetId) {
        return {
          ...node,
          children: [
            ...node.children,
            { 
              id: `${targetId}-${Date.now()}`, 
              name: `新文件夹${node.children.length + 1}`, 
              children: [] 
            }
          ]
        };
      }
      if (node.children.length > 0) {
        return { ...node, children: addSubFolder(node.children, targetId) };
      }
      return node;
    });
  };

  const handleAddFolder = () => {
    if (!selectedFolderId) return; // 未选中时不执行
    setFolders(prev => addSubFolder(prev, selectedFolderId));
  };

  return (
    <div style={{ display: 'flex', gap: '20px', padding: '20px' }}>
      {/* 文件夹树区域 */}
      <div style={{ minWidth: '300px', border: '1px solid #eee', padding: '10px' }}>
        {folders.map(folder => (
          <FolderNode
            key={folder.id}
            folder={folder}
            selectedId={selectedFolderId}
            onSelect={setSelectedFolderId}
          />
        ))}
      </div>
      {/* 侧边操作栏 */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
        <button 
          onClick={handleAddFolder}
          disabled={!selectedFolderId}
          style={{ padding: '8px 16px', cursor: 'pointer' }}
        >
          Add
        </button>
      </div>
    </div>
  );
}

递归子组件(FolderNode)

负责渲染单个文件夹节点,处理展开/折叠、选中状态:

import { useState } from 'react';

export default function FolderNode({ folder, selectedId, onSelect }) {
  const [isExpanded, setIsExpanded] = useState(true);

  const handleClick = () => {
    onSelect(folder.id);
  };

  const toggleExpand = (e) => {
    e.stopPropagation(); // 避免触发选中事件
    setIsExpanded(!isExpanded);
  };

  return (
    <div style={{ marginBottom: '8px' }}>
      {/* 文件夹头部 */}
      <div 
        onClick={handleClick}
        style={{ 
          padding: '4px 8px',
          backgroundColor: selectedId === folder.id ? '#e6f7ff' : 'transparent',
          borderRadius: '4px',
          cursor: 'pointer',
          display: 'flex',
          alignItems: 'center',
          gap: '6px'
        }}
      >
        {/* 展开/折叠图标 */}
        {folder.children.length > 0 && (
          <span onClick={toggleExpand}>
            {isExpanded ? '▼' : '▶'}
          </span>
        )}
        <span>📁 {folder.name}</span>
      </div>
      {/* 渲染子文件夹 */}
      {isExpanded && folder.children.length > 0 && (
        <div style={{ paddingLeft: '20px' }}>
          {folder.children.map(child => (
            <FolderNode
              key={child.id}
              folder={child}
              selectedId={selectedId}
              onSelect={onSelect}
            />
          ))}
        </div>
      )}
    </div>
  );
}

3. 关键功能说明

  • 层级渲染:通过递归组件FolderNode自动处理任意深度的文件夹嵌套,子节点通过paddingLeft实现视觉缩进。
  • 选中状态管理:父组件维护selectedFolderId,点击文件夹时更新该状态,选中项高亮显示。
  • 添加文件夹逻辑:addSubFolder函数递归遍历文件夹树,找到选中的节点后插入新的子文件夹,保证层级正确。
  • 禁用逻辑:未选中任何文件夹时,Add按钮处于禁用状态,避免无效操作。

内容的提问来源于stack exchange,提问作者SerbianDeveloper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 21:13:13