Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
331 views
in Technique[技术] by (71.8m points)

reactjs - Deleting an object from an array not working properly - React-dropzone

I am using react-dropzone to upload some files and display the uploaded files metadata using react-bootstrap-table-next. I try to delete an object from the list of files and if I go about randomly deleting files from the list, it doesnt work properly. Please advice.

This is my codesandbox link: link

This is my code:

import "./styles.css";
import { Box } from "reflexbox/styled-components";
import { isEmpty, reject } from "lodash";
import BootstrapTable from "react-bootstrap-table-next";
import paginationFactory from "react-bootstrap-table2-paginator";
import React, { useState, useCallback } from "react";
import { useDropzone } from "react-dropzone";
import { IconNames } from "@blueprintjs/icons";

import { NonIdealState, Text, Button, Colors, Icon } from "@blueprintjs/core";

const getFormattedFileSize = (bytes, decimals = 2) => {
  if (bytes === 0) return "0 Bytes";

  const k = 1024;
  const dm = decimals < 0 ? 0 : decimals;
  const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];

  const i = Math.floor(Math.log(bytes) / Math.log(k));

  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
};

function Basic(props) {
  const [myFiles, setMyFiles] = useState([]);

  const onDrop = useCallback(
    (acceptedFiles) => {
      const files = [...myFiles, ...acceptedFiles];
      const filesWithId = files.map((item, index) => {
        return {
          id: index + 1,
          lastModified: item.lastModified,
          lastModifiedDate: item.lastModifiedDate,
          name: item.name,
          size: item.size,
          type: item.type,
          webkitRelativePath: item.webkitRelativePath
        };
      });
      setMyFiles(filesWithId);
    },
    [myFiles]
  );

  const { getRootProps, getInputProps } = useDropzone({
    accept: "image/jpeg",
    onDrop
  });

  const removeFile = (file) => {
    console.log("file", file);
    const newFiles = [...myFiles];
    setMyFiles(reject(newFiles, { id: file.id }));
  };

  const fileSizeFormatter = (cell) => {
    return <span>{getFormattedFileSize(cell)}</span>;
  };

  const fileNameFormatter = (cell) => {
    return <Text ellipsize>{cell}</Text>;
  };

  const fileDeleteFormatter = (cell, row) => {
    return (
      <Button
        minimal
        icon={<Icon icon={IconNames.TRASH} color={Colors.RED1} />}
        onClick={() => removeFile(row)}
      />
    );
  };

  const uploadedFilesColumns = [
    {
      dataField: "name",
      text: "File Name",
      formatter: fileNameFormatter,
      sort: true
    },
    {
      dataField: "size",
      text: "File Size",
      formatter: fileSizeFormatter,
      sort: true
    },
    {
      dataField: "delete",
      text: "Delete",
      formatter: fileDeleteFormatter
    }
  ];
  console.log(myFiles);

  return (
    <section className="container">
      <div {...getRootProps({ className: "dropzone" })}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
      <Box className="border p-3">
        <Box
          {...getRootProps({ className: "dropzone" })}
          style={{ cursor: "pointer" }}
        >
          <input {...getInputProps()} accept=".jpg" />
          <NonIdealState
            icon={"import"}
            title="Drag 'n' drop some files here, or click to select files"
          />
        </Box>
        {!isEmpty(myFiles) && (
          <Box className="pt-1">
            <BootstrapTable
              bootstrap4
              keyField="id"
              data={myFiles}
              columns={uploadedFilesColumns}
              pagination={paginationFactory({ showTotal: true })}
            />
          </Box>
        )}
      </Box>
    </section>
  );
}

export default Basic;

Images Link: Images link

Screenshot: enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The issue seems solve when you changing:

const removeFile = (file) => {
    console.log("file", file);
    const newFiles = [...myFiles];
    setMyFiles(reject(newFiles, { id: file.id }));
  };

by calling the old state value directly in setMyFiles() :

 const removeFile = (file) => {
    console.log("file", file);

    setMyFiles((oldStateVal) => reject(oldStateVal, { id: file.id }));
  };

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...