如何防止多次调用React渲染功能?

时间:2019-05-31 01:58:44

标签: react-16

我正在使用React v16.8的上传文件功能,该功能允许用户上传一些pdf文件。 enter image description here 1.当用户单击上载组件以上载文件时,文件上载组件应显示文件名(如果名称已经存在,则应使用新文件名替换原始名称)。 2.如果使用者已上传文件,则文件上传组件应显示从数据库获取的文件名。 3.如果未上传任何文件,则文件上传组件应显示默认字符串:“浏览PDF文件”。现在,我的代码可以在2和3上正常工作,但是一旦我上传了文件,它将使应用程序崩溃。错误消息是: enter image description here

我的代码是:

// DEPENDENCIES
import React, { useState, useEffect } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUpload } from '@fortawesome/free-solid-svg-icons';

// STATE PROVIDERS
import { getState } from '../../../providers/StateProvider';

// STYLES
import FileUploadStyles from './FileUpload.styles';

export default function FileUpload(props) {
  // GET STATE
  const [{ selectedCompanyMember }] = getState();
  console.log(selectedCompanyMember);
  // DESTRUCTURE PROPS
  const { element, data, updateData } = props;
  // LOCAL STATE
  const [file, updateFile] = useState(null);

  const convertFile = fileToConvert =>
    new Promise((resolve, reject) => {
      const fileReader = new FileReader();
      let base64;
      switch (fileToConvert.type) {
        case 'application/pdf':
          fileReader.onload = fileLoadedEvent => {
            base64 = fileLoadedEvent.target.result;
            resolve({
              data: base64,
              name: `${fileToConvert.name.replace(/.pdf/gi, '')}`,
              format: 'pdf',
              type: 'blob'
            });
          };
          fileReader.readAsDataURL(fileToConvert);
          break;
        default:
          reject(new Error('File Format Unsupported'));
      }
    });

  const updateFileData = async fileToProcess => {
    try {
      const convertedFileData = await convertFile(fileToProcess);
      // const fName = `${convertedFileData.name}.${convertedFileData.format}`;
      const newData = { ...data };
      newData[element.key] = convertedFileData;
      updateData({ ...newData });
      updateFile(fileToProcess);
    } catch (error) {
      if (process.env.NODE_ENV !== 'production') {
        console.log('update file data error', error);
      }
    }
  };

  useEffect(() => {
    document.getElementById(element.key).value = null;
    updateFile(null);
  }, [selectedCompanyMember]);
  // this parseFileName function takes fileData which, is from its parent component,
  // contains uploaded file data from server side
  // fileElement is the each file upload element, in this case, it has 4 elemets
  // This Fileupload shows as:
  // <FileUpload key={element.key} element={element} data={data} updateData={updateData} />
  const parseFileName = (fileData, fileElement) => {
    if (fileData && fileElement) {
      const fileName = fileData[fileElement.key];
      if (!fileName) return 'Browse PDF files';
      console.log(fileName); // 4f7ad839-ef94-4c37-9d4c-854a8d94d888-1559158235367-sample.pdf
      let fileNames = [];
      fileNames = fileName.split('-');
      return fileNames[fileNames.length - 1];
    }
    return 'Browse PDF files';
  };

  return (
    <FileUploadStyles>
      {element.label !== false ? (
        <span className={`${!element.label ? 'hidden' : 'label'}`}>{element.label}</span>
      ) : null}
      <div className="upload">
        <FontAwesomeIcon className="upload__icon" icon={faUpload} />
        <button
          onClick={() => {
            document.getElementById(element.key).click();
          }}
          type="button"
          className="upload__button"
        >
          {/* data is passed from its parent component, which is the file data from server side  */}
          {/* element is passed from its parent component, which is the 4 children file upload component */}
          {file ? file.name : parseFileName(data, element)}
        </button>
        <input
          onChange={ev => {
            const uploadedFile = ev.target.files[0];
            updateFileData(uploadedFile);
          }}
          type="file"
          id={element.key}
        />
      </div>
    </FileUploadStyles>
  );
}

我没有得到的一件事是我上传了一个文件,我的理解是{file ? file.name : parseFileName(data, element)}它应该返回文件名,但是为什么在parseFileName函数中:fileNames = fileName.split('-');将运行并得到错误消息显示:fileName.split不是函数。我假设parseFileName被调用了很多次,有时文件名可能未定义,导致此错误。有人可以帮助我解决这个问题吗?非常感谢您!

0 个答案:

没有答案