react 文件选择器

发布时间 2023-12-28 16:29:39作者: laremehpe
export type FileSelectorType = {
  emit: boolean;
  type: "file" | "dir";
  callBack: (path: string, fileList: FileList) => void;
};

export const FileSelector = (props: { upload: FileSelectorType }) => {
  useEffect(() => {
    const input = document.createElement("input");
    input.setAttribute("id", "uploadInputBox");
    props.upload.type === "dir" &&
      input.setAttribute("webkitdirectory", "true");
    input.setAttribute("multiple", "true");
    input.setAttribute("type", "file");
    // input.setAttribute("style", "width: 0px;");
    input.addEventListener("change", (e) => {
      const target = e.target as HTMLInputElement;
      let path = "";
      if (target.files.length) {
        const ele = target.files[0];
        const relativePath = ele.webkitRelativePath.substring(
          0,
          ele.webkitRelativePath.lastIndexOf("/")
        );
        path = ele.path.substring(
          0,
          ele.path.lastIndexOf(relativePath) + relativePath.length
        );
      }

      props.upload.callBack(path, target.files);
    });
    document.getElementById("uploadInputBox").append(input);
    input.click();

    return () => {
      document.getElementById("uploadInputBox").removeChild(input);
    };
  }, [props.upload.emit]);
  return (
    <div id="uploadInputBox" style={{ width: 0, height: 0, opacity: 0 }}></div>
  );
};
// 调用:
  const [upload, setUpload] = useState<FileSelectorType>({
    emit: false,
    type: "dir",
    callBack: (path: string, fileList: FileList) => {},
  });

<FileSelector upload={upload} />

<Button
      onClick={() => {
        setUpload({
          emit: !upload.emit,
          type: "dir",
          callBack: (path: string, fileList: FileList) => {
            console.log(path);
            setBackupFolder(path);
          },
        });
      }}
    >
    choose folder
</Button>