Build a file system explorer in React

Trying to search for information around file explorers in React ridiculously difficult. The primary results always seem to involve the most ideal folder structure for a React project, and nothing else. This is suprisingly a fraction less interesting than the actual topic I was after, so I wanted to create a simple and quick tutorial on how to make a basic file explorer using React components and logic. For ease of use, I'm also using the classnames and tailwindcss for atomic components in a way that I enjoy.

Configuring your React interactive file system

Reading the below sample config should allow you to get a quick idea on how a config would look like for an interactive file system:

let fileExplorerData = {
   "name": "main",
   "type": "folder",
   "items": [
      {
         "type": "file",
         "name": ".gitignore"
      }
   ]
}

With this above config, we'd expect a folder called main with a single file, .gitignore.

The basic methodology here is that each object is an "Item", and each "Item" can render subsequent items if it's a folder, but if not, it will be the end of a nose.

Rendering using a recursive "Item" component

let Item = props => {
   let {contents} = props
   let {name, type} = contents

   
   // Following items, or "false" to indicate this is the end.
   let items = type === "folder"? contents["items"]: false
   
   return (
     <div>
        {name}
        {items?(
           <div className="ml-5">

             items.map((item, i) => {
               return (<Item key={i} contents={item} />)
             })

           </div>
        }: false}
     </div>
   )
}

This will directly render a basic component recursively till completing all nodes, and all folders. I personally added more features including a clickable expand and retract which maintans state for my cloud data platform file system YDP (Your Data Place), which also stores text and adds attributes to each file. Below are some other additional code snippets you can incorporate into your code to add some functionality.

Additional functionality and code snippets

You may want to apply a sorting function to the subsequently rendered items in order to maintain some sort of standard rendering logic to ensure that your interactive component has order. This can be done by adding .sort to the items.map section, and add in some function folderFirstSort which is defined as below (this function sorts folders above files):

let folderFirstSort = (a, b) => {
   if (a.type === "folder" && b.type === "folder") {
      return 0
   } else if (a.type === "folder" && b.type !== "folder") {
      return -1
   } else if (a.type !== "folder" && b.type === "folder") {
      return 1
   }
}

Further, you can add expanded state (true/false) which can direct whether or not to hide the subsequent items.

Enjoy!

Comments

Popular posts from this blog

Shareable data and code in YDP Projects

Siesta of YDP

The start: a week of Rust