【问题标题】:Drag Files & Select Files to React拖动文件并选择要反应的文件
【发布时间】:2021-12-09 10:39:06
【问题描述】:

我正在做一个应用程序,我必须上传一个文件列表,或者我可以选择一个按钮并且文件上传是打开的,你推荐任何库还是我只是使用 input 元素来做原生?

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    为了更好地控制样式和自定义 vanilla JS。这是一个简单的文件选择器组件,它支持将文件拖放到列表中。

    const DropOrChooseFile = () => {
      const [files, setFiles] = React.useState([]);
    
      const onDropHandler = (ev) => {
        ev.preventDefault();
    
        let file = "";
        if (ev.dataTransfer.items) {
          // Use DataTransferItemList interface to access the file(s)
          file =
            [...ev.dataTransfer.items]
              .find((item: any) => item.kind === "file")
              .getAsFile() ;
        } else {
          // Use DataTransfer interface to access the file(s)
          file = ev.dataTransfer.files[0];
        }
        setFiles([...files, file]);
      };
    
      const onDragOver = (ev) => ev.preventDefault();
    
      return (
        <div>
          <div> Selected files: </div>
          {files.map((file) => (
            <div key={file.name} style={{color: "green",fontWeight: "bold" }}>{file.name}</div>
          ))}
          <div style={{marginTop: 20}}></div>
          <div id="drop_zone" onDrop={onDropHandler} onDragOver={onDragOver}>
            <div>Drag and drop a file here</div>
            <div> or </div>
            <label htmlFor={"file_picker"} className="fp-label">
              Select file
            </label>
            <input
              id="file_picker"
              type="file"
              accept="image/png, image/jpeg"
              onChange={(ev) => {
                setFiles([...files, ev.target.files[0]]);
              }}
              style={{display: "none"}}
            ></input>
          </div>
        </div>
      );
    };
    
    
    ReactDOM.render(<DropOrChooseFile />, document.getElementById("app"));
    #drop_zone {
        display: grid;
        width: 400px;
        place-content: center;
        border: 2px dashed lightgray;
        padding: 16px;
        text-align: center;
    }
    
    .fp-label {
      border: 1px solid lightgray;
      border-radius: 5px;
      padding: 8px;
    }
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    
    <div id="app"></div>

    【讨论】:

      【解决方案2】:

      根据您提供的信息,您的要求似乎可以通过简单的(本机)输入 type=file 和细微的 UI 调整来满足。

      但是,在决定是否为此案例安装新软件包之前,您应该考虑以下事项。

      在一个案例中,您有一个文件列表:

      • 它可能需要一个队列来上传列表,从而提高上传文件的效率(和安全性)。 #UX, #reliability

      • 上传时,绝对需要一个动画来说明每个文件的进度。 #UX

      • 多个选定的文件可能包含无意中选择的不需要的文件,上传必须是可取消的(消除上传其余文件的可能请求)。 #UX

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-05
        • 2014-05-27
        • 2017-05-27
        • 1970-01-01
        • 2010-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多