代码之家  ›  专栏  ›  技术社区  ›  Matvey Androsyuk

如何使用React在树结构中呈现我的组件,就像IDE中的默认文件结构一样

  •  1
  • Matvey Androsyuk  · 技术社区  · 6 月前

    我有一个名为TreeNode的组件,它是我树结构中的一个文件。

    import React from "react";
    import classes from "./TreeNode.module.css"
    
    function TreeNode({children, title}){
        return(
            <div>
                <div className={classes.treeNode}>
                    <div className={classes.treeNodeType}>
                        <svg xmlns="http://www.w3.org/2000/svg" fill="#3B4045" x="0px" y="0px" width="20" height="20" viewBox="0 0 20 20">
                            <path d="M20,6h-8l-2-2H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z"></path>
                        </svg>
                    </div>
                    <div className={classes.treeNodeTitle}>
                        {title}
                    </div>
                </div>
            </div>
        )
    }
    
    export default TreeNode;
    

    我有一个文件,其中包含文件的模拟对象,我想像树一样在我的页面上漫游。

    const files = [
        {
            id: 232141332,
            title: "Оборудование",
            type: "FOALDER",
            opened: false,
            level: 0,
            fatherId: null,
            children: [
                {
                    id: 734573086,
                    title: "MA5600",
                    type: "FOALDER",
                    opened: false,
                    level: 1,
                    fatherId: 232141332,
                    children: [
                        {
                            id: 867407333,
                            title: "Удаление платы",
                            type: "FILE",
                            opened: false,
                            level: 2,
                            fatherId: 734573086,
                            children: []
                        },
                        {
                            id: 110345245,
                            title: "Добавление платы",
                            type: "FILE",
                            opened: false,
                            level: 2,
                            fatherId: 734573086,
                            children: []
                        }
                    ]
                },
                {
                    id: 222225454,
                    title: "C300M",
                    type: "FOALDER",
                    opened: false,
                    level: 1,
                    fatherId: 232141332,
                    children: [
                        {
                            id: 333334256,
                            title: "Не найдена опция TR-82",
                            type: "FILE",
                            opened: false,
                            level: 2,
                            fatherId: 222225454,
                            children: []
                        }
                    ]
                }
            ]
        }
    ]
    
    export default files;
    

    如何编写Main.jsx文件来渲染所有这些文件。

    import files from "../../mock/files";
    import "../../styles/Main.css"
    import TreeNode from "../treenode/TreeNode";
    
    function Main() {
        return (
          <div className="wrapper">
            <div className="tree">
                {
                    files.map((file) => {
                        //code
                    })
                }
            </div>
          </div>
        );
      }
      
      export default Main;
    

    也许我需要重构一些代码,我不知道,但第二天我做不到。

    2 回复  |  直到 6 月前
        1
  •  1
  •   Sergey Sosunov    6 月前

    只需使用递归。类似 this stackoverflow question .

    稍微调整了一下你的组件,但我希望你能理解整体想法。

    const files = [
      {
        id: 232141332,
        title: "Оборудование",
        type: "FOALDER",
        opened: false,
        level: 0,
        fatherId: null,
        children: [
          {
            id: 734573086,
            title: "MA5600",
            type: "FOALDER",
            opened: false,
            level: 1,
            fatherId: 232141332,
            children: [
              {
                id: 867407333,
                title: "Удаление платы",
                type: "FILE",
                opened: false,
                level: 2,
                fatherId: 734573086,
                children: [],
              },
              {
                id: 110345245,
                title: "Добавление платы",
                type: "FILE",
                opened: false,
                level: 2,
                fatherId: 734573086,
                children: [],
              },
            ],
          },
          {
            id: 222225454,
            title: "C300M",
            type: "FOALDER",
            opened: false,
            level: 1,
            fatherId: 232141332,
            children: [
              {
                id: 333334256,
                title: "Не найдена опция TR-82",
                type: "FILE",
                opened: false,
                level: 2,
                fatherId: 222225454,
                children: [],
              },
            ],
          },
        ],
      },
    ];
    
    const classes = {/* dummy to prevent runtime errors*/};
    
    function TreeNode({ item }) {
      return (
        <div className={classes.treeNode}>
          <div className={classes.treeNodeType}>
            <svg
              xmlns="http://www.w3.org/2000/svg"
              fill="#3B4045"
              x="0px"
              y="0px"
              width="20"
              height="20"
              viewBox="0 0 20 20"
            >
              <path d="M20,6h-8l-2-2H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z"></path>
            </svg>
          </div>
          <div className={classes.treeNodeTitle}>{item.title}</div>
          <div>
            {item.children?.map((x) => (
              <TreeNode key={x.id} item={x} />
            ))}
          </div>
        </div>
      );
    }
    
    const App = () => {
      return (
        <div>
          {files.map((x) => (
            <TreeNode key={x.id} item={x} />
          ))}
        </div>
      );
    };
    
    ReactDOM.render(<App/>, document.getElementById('app'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="app"/>
        2
  •  0
  •   Abhay Dedkawala    6 月前
    1. 你需要使用 Recursion 在里面 TreeNode 功能。
    2. In <App /> 组件传递文件 [ parent object ] 在里面 <TreeNode /> 组件作为参数。
    3. In <树节点/> 部件传递儿童 [ child object ] 在里面 <树节点/> 组件作为参数。
    4. <树节点/> 组件集 margin-left 根据显示文件夹的级别值设置样式&;按文件夹或树视图显示文件。

    const data = [
      {
        id: 232141332,
        title: "Оборудование",
        type: "FOLDER",
        opened: false,
        level: 0,
        fatherId: null,
        children: [
          {
            id: 734573086,
            title: "MA5600",
            type: "FOLDER",
            opened: false,
            level: 1,
            fatherId: 232141332,
            children: [
              {
                id: 867407333,
                title: "Удаление платы",
                type: "FILE",
                opened: false,
                level: 2,
                fatherId: 734573086,
                children: [],
              },
              {
                id: 110345245,
                title: "Добавление платы",
                type: "FILE",
                opened: false,
                level: 2,
                fatherId: 734573086,
                children: [],
              },
            ],
          },
          {
            id: 222225454,
            title: "C300M",
            type: "FOLDER",
            opened: false,
            level: 1,
            fatherId: 232141332,
            children: [
              {
                id: 333334256,
                title: "Не найдена опция TR-82",
                type: "FILE",
                opened: false,
                level: 2,
                fatherId: 222225454,
                children: [],
              },
            ],
          },
        ],
      },
    ];
    
    function TreeNode({ files }) {
      return (
        <div style={{ margin: 10, marginLeft: files.level > 0 ? ( files.level + 1 ) * 10 : 10 }}>
          <i className={"fa-regular " + (files.type === "FOLDER" ? "fa-folder" : "fa-file")}></i>
          <span style={{ marginLeft: 10 }}>{files.title}</span>
    
          {files.children.map((file, index) => (
            <TreeNode key={index} files={file} />
          ))}
        </div>
      );
    }
    
    function App() {
      return data.map((file, index) => <TreeNode key={index} files={file} />);
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.0/umd/react-dom.production.min.js"></script>
    <div id="root"></div>