首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在ReactJs中使用dropzone将文件及其描述添加到状态?

如何在ReactJs中使用dropzone将文件及其描述添加到状态?
EN

Stack Overflow用户
提问于 2020-10-13 08:11:55
回答 2查看 411关注 0票数 4

如何使用select,使用react-dropzone向组件的状态添加一个或多个文件及其描述。

我正在使用Reactjs,dropzone和bootstrap,我想要实现的是:添加一个或多个文件(通过拖动它们到一个区域),然后看到添加的文件列表和每个文件的选择输入(带有用户定义“类型”的选项),将所有这些保存在一个状态中,然后将该信息发送到API。类似于图像中显示的内容:

到目前为止,我的代码根据文件的扩展名(pdf、xlsx ...)返回了一个可接受的文件列表。和被拒绝的文件,但我不知道如何添加select (带有选项"type "from file,可以是“summary ",”report ",“test "...)并将其保存在一个状态中,然后将其发送到API。

到目前为止,我使用react-dropzone编写的代码如下:

代码语言:javascript
运行
复制
const baseStyle = {
  flex: 1,
  display: "flex",
  flexDirection: "column",
  alignItems: "center",
  padding: "20px",
  borderWidth: 2,
  borderRadius: 20,
  borderColor: "#26C2E7",
  borderStyle: "dashed",
  backgroundColor: "#fafafa",
  color: "#c4c4c4",
  outline: "none",
  transition: "border .24s ease-in-out"
};

const activeStyle = {
  borderColor: "#f2f"
};

const acceptStyle = {
  borderColor: "#f8f"
};

const rejectStyle = {
  borderColor: "#f2f"
};
function InputFiles(props) {
  const {
    acceptedFiles,
    fileRejections,
    isDragActive,
    isDragAccept,
    isDragReject,
    getRootProps,
    getInputProps
  } = reactDropzone.useDropzone({
    accept: ".xlsx,.docx,.pdf"
  });

  const style = React.useMemo(
    () => ({
      ...baseStyle,
      ...(isDragActive ? activeStyle : {}),
      ...(isDragAccept ? acceptStyle : {}),
      ...(isDragReject ? rejectStyle : {})
    }),
    [isDragActive, isDragReject, isDragAccept]
  );

  const acceptedFileItems = acceptedFiles.map((file) => (
    <li key={file.path}>
      {file.path} - {file.size} bytes
    </li>
  ));

  const fileRejectionItems = fileRejections.map(({ file, errors }) => (
    <li key={file.path}>
      {file.path} - {file.size} bytes
      <ul>
        {errors.map((e) => (
          <li key={e.code}>{e.message}</li>
        ))}
      </ul>
    </li>
  ));

  return (
    <section className="container">
      {/* <div {...getRootProps({ style })}> */}
      <div {...getRootProps({ style })}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
        <em>(Only *.pdf , *.xlsx , *.docx files will be accepted)</em>
      </div>
      <aside>
        <h4>Accepted files</h4>
        <ul>{acceptedFileItems}</ul>
        <h4>Rejected files</h4>
        <ul>{fileRejectionItems}</ul>
      </aside>
    </section>
  );
}

ReactDOM.render(<InputFiles />, document.body);

window.onload = function() {
 console.log('onload');
   
}
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dropzone/11.2.0/index.js"></script>

我们的目标是得到这样的东西:

在添加文件及其描述时,它们必须保存在组件的状态中,目的是在单击保存时向API发出POST请求,而在单击取消时必须删除状态信息

EN

Stack Overflow用户

回答已采纳

发布于 2020-10-17 11:22:47

正如@Emmanuel在他的回答中提到的,您可以将文件存储在一个状态中,此实现使用名称作为键将文件存储在映射中。

代码语言:javascript
运行
复制
import React, { useMemo, useState } from "react";
import { useDropzone } from "react-dropzone";

const baseStyle = {
  flex: 1,
  display: "flex",
  flexDirection: "column",
  alignItems: "center",
  padding: "20px",
  borderWidth: 2,
  borderRadius: 20,
  borderColor: "#26C2E7",
  borderStyle: "dashed",
  backgroundColor: "#fafafa",
  color: "#c4c4c4",
  outline: "none",
  transition: "border .24s ease-in-out"
};

const activeStyle = {
  borderColor: "#f2f"
};

const acceptStyle = {
  borderColor: "#f8f"
};

const rejectStyle = {
  borderColor: "#f2f"
};
function InputFiles(props) {
  const [files, setFiles] = useState({});
  const {
    fileRejections,
    isDragActive,
    isDragAccept,
    isDragReject,
    getRootProps,
    getInputProps
  } = useDropzone({
    onDrop: (acceptedFiles) => {
      setFiles((prevFiles) =>
        acceptedFiles.reduce(
          (acc, file) => ({
            ...acc,
            [file.name]: {
              file,
              fileType: ""
            }
          }),
          prevFiles
        )
      );
    },
    accept: ".xlsx,.docx,.pdf"
  });
  const style = useMemo(
    () => ({
      ...baseStyle,
      ...(isDragActive ? activeStyle : {}),
      ...(isDragAccept ? acceptStyle : {}),
      ...(isDragReject ? rejectStyle : {})
    }),
    [isDragActive, isDragReject, isDragAccept]
  );
  const acceptedFileItems = Object.keys(files).map((fileName) => {
    const currentFile = files[fileName].file;
    const onSelectChange = (e) => {
      e.persist();
      setFiles((prevFiles) => {
        return {
          ...prevFiles,
          [fileName]: {
            ...prevFiles[fileName],
            fileType: e.target.value
          }
        };
      });
    };

    return (
      <li key={fileName}>
        <div style={{ display: "flex" }}>
          <span>
            {currentFile.path} - {currentFile.size} bytes
          </span>
          <select value={currentFile.fileType} onChange={onSelectChange}>
            <option value=""></option>
            <option value="summary">summary</option>
            <option value="description">report</option>
            <option value="report">description</option>
          </select>
        </div>
      </li>
    );
  });

  const fileRejectionItems = fileRejections.map(({ file, errors }) => (
    <li key={file.path}>
      {file.path} - {file.size} bytes
      <ul>
        {errors.map((e) => (
          <li key={e.code}>{e.message}</li>
        ))}
      </ul>
    </li>
  ));

  return (
    <section className="container">
      {/* <div {...getRootProps({ style })}> */}
      <div {...getRootProps({ style })}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
        <em>(Only *.pdf , *.xlsx , *.docx files will be accepted)</em>
      </div>
      <aside>
        <h4>Accepted files</h4>
        <ul>{acceptedFileItems}</ul>
        <h4>Rejected files</h4>
        <ul>{fileRejectionItems}</ul>
        <button onClick={() => console.log(files)}>console log files</button>
      </aside>
    </section>
  );
}

export default InputFiles;

你可以在这里查看https://codesandbox.io/s/react-drop-zone-select-vhc2l

票数 2
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64326872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档