Home > Software engineering >  How to select files within a directory and capture them in a state including relative path
How to select files within a directory and capture them in a state including relative path

Time:01-13

I am looking for a way to select files through the file dialogue. The file selector needs to:

  • be restricted to only directory selection

  • capture all selected files in a single callback so that they can be set to a state

  • include the relative path for all files in the file list

I've tried the file selector components from a few libraries such as antd, react-dropzone, @rpldy/uploady, react-file-reader, and react-file-picker already, but none seem to be able to fulfill all three requirements.

CodePudding user response:

You can achieve this with Uploady.

When using the webkitdirectory flag for the file input element, you do get the webkitRelativePath property in all browsers (at least chrome & firefox) per the spec.

Now, to get the list of files, you'd use the useBatchAddListener hook.

import React, { useState } from "react";
import Uploady, { useBatchAddListener } from "@rpldy/uploady";
import UploadButton from "@rpldy/upload-button";

const MyUploadButton = ({ addFilesToState }) => {
  useBatchAddListener((batch) => {
    addFilesToState(batch.items.map(({ file }) => file));
  });

  return <UploadButton>Upload Files</UploadButton>;
};

const Uploader = () => {
  const [_, setFiles] = useState([]);

  return (
    <MyUploadButton
      addFilesToState={(files) => setFiles((prev) => [...prev, ...files])}
    />
  );
};

export default function App() {
  return (
    <Uploady destination={{ url: "[upload-url]" }} webkitdirectory="true" debug>
      <div className="App">        
        <Uploader />
      </div>
    </Uploady>
  );
}

See sandbox.

CodePudding user response:

Not sure if there is a React library for that, but you can take a look at the File System Access API. It only works in Chrome, though, but maybe that <input type="file" webkitdirectory> works in other browsers and would be enough for your needs.

  • Related