- About
- Installation
- Overview
- Implementation and choices
- Things to do
- Dependencies
- Development dependencies
This repository contains a file explorer component built with React and Sass. It renders a set of directory trees served by a backend API, and is updated on file changes through a WebSocket connection.
Clone the repository with git:
git clone git@github.com:ycandau/explorer.gitChange directory to the root of the repository:
cd explorerInstall all the dependencies with yarn:
yarn installSetup the local environment variables in the .env file:
PORT=3000
REACT_APP_WEBSOCKET_URL=ws://localhost:8000Run the app in development mode. Open http://localhost:3000 to view it in the browser.
yarn startThe app needs the backend API found here. Start the backend server before starting the app.
Here is the component embedded in a page, in dark mode:
And in light mode:
The dark and light themes are controlled from a toggle and implemented using CSS variables and data attribute selectors.
Folders and non folders are colored differently to make it easier to distinguish them.
A folder can be expanded and collapsed by clicking anywhere on the corresponding highlighted line.
A little extra feedback is provided to the user with a CSS color and scale transition on the caret icon, when the cursor hovers over the line.
The whole tree can be closed by clicking on the cross situated at the right of the root folder.
I used React's functional components since it is the recommended approach in the latest versions of the framework.
To manage the app state I considered three alternatives:
- Multiple
useState()hooks. - A single
useReducer()hook with a reducer function. - A dedicated state container library like Redux.
I adopted the second option as I find that it is much easier to write modular code with a reducer, but the state wasn't complex enough to justify using a library such as Redux.
To keep the code modular I use a number of custom hooks to:
- Manage the application state.
- Fetch initial data from the server once after the first render.
- Establish the WebSocket connection with the server.
- Update the server when folders are expanded or collapsed.
- Update the server when trees are closed.
The component seems to run smoothly even with large folders such as node_modules. As discussed in the README for the server, only data on expanded folders is exchanged to avoid a brute force recursion through the full folder structure. The component also takes advantage of information on the tree structure included in the arrays sent by the server.
Some of the user actions are well suited for optimistic rendering. When collapsing a folder or closing a tree we can update the local state before sending the asynchronous request to the server. On the other hand, expanding a folder does require waiting for the response from the server.
I considered providing visual feedback to indicate the status of asynchronous requests (loading and such...). But due to the short delays I decided against it as a brief flicker might be more distracting than helpful.
- Resizable sections
- A way to add trees from the file explorer
- Filtering by glob or regex patterns
- File type icons
- Custom scroll bars
- React: A JavaScript library for building user interfaces.
- axios: Promise based HTTP client for the browser and Node.js.
- react-fontawesome: Font Awesome 5 React components using SVG.
- Sass: CSS extension language.

