在功能组件中导入/获取数据会减慢页面加载

时间:2019-09-17 02:28:09

标签: reactjs import axios fetch react-hooks

我有一个功能部件,在一个页面上被调用了100多次。在该组件中,我导入了axios,并有一些axios调用,这些调用在该组件内的各种操作上会有所变化。

由于经验证据,我相信在此组件中导入Axios会大大降低页面加载速度。假设这是真的,我应该如何提取axios的导入来加快速度?

// component.jsx

import React, { useState, useEffect, useMemo } from 'react';
import { useSelector } from 'react-redux'
import { useDropzone } from 'react-dropzone';

import axios from 'axios';
// import fetch from 'isomorphic-fetch';
import { Progress } from 'reactstrap';
import { push } from 'react-router-redux';
import { SERVER_URL } from '../../utils/config';

const baseStyle = {
  flex: 1,
  display: 'flex',
};

const activeStyle = {
  borderColor: '#2196f3'
};

const acceptStyle = {
  borderColor: '#00e676'
};

const rejectStyle = {
  borderColor: '#ff1744'
};



function StyledDropzone(props) {
  const token = useSelector(state => state.auth.token);
  const files = props.inputProps.files;


  const [myFiles, setFiles] = useState(props.inputProps.files);

  const {acceptedFiles, getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject} = useDropzone({
    getFilesFromEvent: event => myCustomFileGetter(event, props),
    accept: 'image/*,*.doc,*.doc,*.xls*,*.pdf',
    onDrop: (acceptedFiles, rejectedFiles) => {
      let accepted = acceptedFiles.map(async file => {
        setFiles(props.inputProps.files.unshift(file));
        let formData = new FormData();
        formData.append("file", file);
        formData.append("filename", file.name)
        formData.append("control", props.inputProps.id);
        let item = await axios.post(`${SERVER_URL}/api/v1/requirements/related_files`, formData, {
            headers: {
              Accept: 'application/json, text/plain, */*',
              Authorization: `Token ${token}`,
            },
            // receive two parameter endpoint url ,form data 
          })
          .then(res => { // then print response status
              return Object.assign(file, {
                preview: URL.createObjectURL(file),
                file_name: response.data.filename
              });
              res.json()
          })

          .then((data) => {
            console.log('success')
            console.log(data);
          })
          .catch(err => {
              if (error && typeof error.response !== 'undefined' && error.response.status === 401) {
                  // Invalid authentication credentials
                  return error.response.json().then((data) => {
                      dispatch(authLoginUserFailure(401, data.non_field_errors[0]));
                      dispatch(push(loginPath));
                  });
              } else if (error && typeof error.response !== 'undefined' && error.response.status >= 500) {
                  // Server side error
                  dispatch(authLoginUserFailure(500, 'A server error occurred while sending your data!'));
              } else {
                  // Most likely connection issues
                  dispatch(authLoginUserFailure('Connection Error', 'An error occurred while uploading the file'));
              }

              dispatch(push(loginPath));
              return Promise.resolve();
          });

        return item;
      });
    }
  });

  const formattedFileList = files.map(f => (
    <li className="fileListItem" key={f.id}>
      {f.name ?  f.name : f.filename}: <input type="text" placeholder="Add a note..."/> <span className="oi oi-pencil" title="Edit the meta information of this file." aria-hidden="true"></span> <span className="oi oi-data-transfer-download" title="Download this file." aria-hidden="true"></span> <span className="oi oi-x" onClick={() => { deleteFile(f.id) }} title="Delete this file." aria-hidden="true"></span>
    </li>
  ));

  const deleteFile = (id) => {
    alert(id)

  }
  // const {
  //   isDragActive,
  //   isDragAccept,
  //   isDragReject
  // } = useDropzone({accept: 'image/*,*.doc,*.doc,*.xls*,*.pdf'});

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

  return (
    <React.Fragment>
      <div {...getRootProps({style})}>
        <input {...getInputProps({ id: props.inputProps.id })} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
      <label className="control-label">Files</label>
      <ul className="fileList">{formattedFileList}</ul>
    </React.Fragment>
  );
}

async function myCustomFileGetter(event, props) {
  const files = [];
  const fileList = event.dataTransfer ? event.dataTransfer.files : event.target.files;

  for (var i = 0; i < fileList.length; i++) {
    const file = fileList.item(i);

    Object.defineProperty(file, 'myProp', {
      value: true
    });

    files.push(file);
  }

  return files;
}

export default StyledDropzone;

1 个答案:

答案 0 :(得分:0)

虽然导入axios绝对不是罪魁祸首,但这是针对您特定问题的解决方案:

为避免在该组件的源文件中导入axios,您可以在父组件的源文件中导入axios并将其通过props向下传递到该组件。像

function StyledDropzone(props) {
    const axios = props.axios;
.....
}

及其上级组件

import axios from 'axios';
.....

<StyledDropzone axios={axios} ....... />