如何使用React上传文件



,因此我目前正在尝试上传文件,并将其保存在Google云上。但是我被困在如何使用React-Redux获取输入文件的情况下。

基本上,我的后端部分已经完成,我使用此命令使用httpie进行了测试 HTTP localhost:8000/v1/... @(file_path)而且效果很好。

现在使用输入标签后: <input type="file" onChange="">我不知道如何获得用户选择的file_path。而且我什至不知道我是否可以使用此方法获取上传文件。

谢谢

您无法通过方法<input type="file" onChange={this.handleChangeFile.bind(this)}>

处理Onchange文件
handleChangeFile(event) {
  const file = event.target.files[0];
  let formData = new FormData();
  formData.append('file', file);
  //Make a request to server and send formData
}

首先:创建一个组件文件名'fileupload.js'

import React, {  Fragment, useState, useEffect } from 'react'

function FileUpload (props) {
    useEffect(() => {
        clearFileUpload()
    }, [])
    const [fileName, setFileName] = useState('')
    const [fileSize, setFileSize] = useState('')
    const [fileSizeKB, setFileSizeKB] = useState('')
    const [fileType, setFileType] = useState('')
    const [src, setSrc] = useState('')
 
    const clearFileUpload = () => {
        setFileName('')
        setFileSize('')
        setFileType('')
        setSrc('')
        props.dataChanger('')
    }
    const onPickFile = (e) => {
        e.preventDefault();
        clearFileUpload()
        document.getElementById(props?.name).click()
    }
    const onFilePicked = (e) => {
        let files = e.target.files;
        let file_name = files[0].name;
        let file_size = getFileSize(files[0].size);
        let file_size_kb = getFileSizeKB(files[0].size);
        let file_type = getFileType(files[0]).toLowerCase();
        setFileName(file_name)
        setFileSize(file_size)
        setFileSizeKB(file_size_kb)
        setFileType(file_type)
        if (props?.max_file_size_in_kb &&  file_size_kb > props?.max_file_size_in_kb) 
        {
            alert('Maximum allowed file size = '+props?.max_file_size_in_kb+ ' kb')
            clearFileUpload()
            return false;
        }
        if (props?.allowed_extensions && !arrToLowerCase(props?.allowed_extensions).includes(file_type)) 
        {
            clearFileUpload()
            alert('Allowed file type = '+props?.allowed_extensions)
            return false;
        }
        
        let fileReader = new FileReader();
        fileReader.addEventListener('load', ()=>{
            // console.log(fileReader.result);
            props.dataChanger(fileReader.result)
            setSrc(fileReader.result)
        })
        fileReader.readAsDataURL(files[0])

    }
    const getFileSize = (file_size) =>
    {
        if ( (file_size/1024) >= 1024 )
        {
            file_size= parseInt((file_size/1024)/1024) + ' MB';
        }
        else{
            file_size=parseInt(file_size/1024) + ' KB';
        }
        return file_size;
    }
    const getFileSizeKB = (file_size) =>
    {
        file_size=parseInt(file_size/1024);
        return file_size;
    }

    const getFileType = (file) =>
    {
        return file?.type.split('/').pop();
    }
    const arrToLowerCase = (arr=[]) => {
        return arr.map(str => str.toLowerCase());
    }

    return (
        <Fragment>
            <button className="btn btn-primary text-capitalize mr-2 mb-2"  onClick={(e) => onPickFile(e)}>{props?.button_title || 'Upload File'}</button>
            
            {(props?.required && fileName?.length<=3 && !src ) ? <label className="label label-danger">Required</label> : ''}
            <br />
            {fileName ? <label className="label label-primary">{fileName}</label> : ''}
            {fileSize ? <label className="label label-info">{fileSize}</label> : ''}
            <br />
            {/* new upload file */}
            {(props?.type=='image' && src && (props?.prev_src)) ? <img src={src}  style={{ maxHeight: "150px",  maxWidth: "150px" }} alt="" className="mt-2" /> : ''}
            
            {/* previous image */}
            {(props?.type=='image' && (props?.prev_src)  && !src) ?  <img src={props?.prev_src}  style={{ maxHeight: "150px",  maxWidth: "150px" }} alt="" className="mt-2" /> : ''}
            
            {(props?.type=='image' && src && (props?.prev_src)) ? <button className="btn btn-danger  btn-outline-danger pl-1 pr-0 py-0 ml-2" onClick={clearFileUpload} title="Remove file"><i className="icofont icofont-ui-close"></i></button> : ''}
            <input className='file d-none' type="file"   data-show-upload="true" data-show-caption="true" 
                id={props?.name} 
                name={props?.name}
                required={props?.required ? true : false} 
                onChange={(e) => onFilePicked(e)}
            /> 
        </Fragment>
    )
}
export default FileUpload

第二:如何在表单中使用此组件

    import FileUpload from './FileUpload.js'
    <FileUpload 
        name="thumbImage" 
        button_title="Thumbnail Image Upload"  
        max_file_size_in_kb="200" 
        dataChanger={(value) => dataChangerThumbnail(value)} 
        type="image"  
        prev_src={'localhost:8001/'+formData?.thumbImage} 
        required 
        allowed_extensions={[ 'jpg', 'jpeg', 'png', 'gif']} 
    /> 
    const dataChangerThumbnail = (value) => {
        setFormData({...formData, thumbImage: value})
    }
    const formInitial = {
        thumbImage: '',
    }
    const [formData, setFormData] = useState(formInitial)

axios和formik

的完整示例
import "./App.css";
import { useEffect, useState } from "react";
import * as Yup from "yup";
import { Formik, Field, Form, ErrorMessage, useField } from "formik";
import axios from "axios";

function App() {
  return (
    <Formik
      initialValues={{
        profile: [],
      }}
      validationSchema={Yup.object({
        profile:Yup.array().min(1,"select at least 1 file")
      })}
      onSubmit={(values, props) => {
        let data = new FormData();
        values.profile.forEach((photo, index) => {
          data.append(`photo${index}`, values.profile[index]);
        });
        axios
          .post("you_api_for_file_upload", data, {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          })
          .then((response) => {
            console.log(response);
          })
          .catch((err) => {
            console.log(err);
          });
      }}
    >
      {(formik) => {
        return (
          <>
            <Form>
              <input
                id="file"
                name="profile"
                type="file"
                onChange={(event) => {
                  const files = event.target.files;
                  let myFiles =Array.from(files);
                  formik.setFieldValue("profile", myFiles);
                }}
                multiple
              />
              <ErrorMessage name="profile"/>
              <button type="submit" disabled={formik.isSubmitting}>
                Submit
              </button>
            </Form>
          </>
        );
      }}
    </Formik>
  );
}
export default App;

希望这会帮助您

结帐此博客,在React中与示例中的上传功能非常好。以下是从上面的博客上传代码:

handleUploadedFiles = files => {
        var reader = new FileReader();
        reader.onload = (e) => {
            //Split csv file data by new line so that we can skip first row which is header
            let jsonData = reader.result.split('n');    
            let data = [];
            jsonData.forEach((element, index) => {
                if(index) {
                     //Split csv file data by comma so that we will have column data
                    const elementRaw = element.split(',');
                    console.log(element, index);
                    if(element) {
                        let param = {
                            'id' : elementRaw[0],
                            'name' : elementRaw[1],
                            'age' : elementRaw[2],
                            'address' : elementRaw[3]
                        }
                        data.push(param);
                    }
                }
            });
        }
        console.log("TCL: Dashboard -> reader.readyState", reader.readyState)          
        reader.readAsText(files[0]);
    }

相关内容

  • 没有找到相关文章

最新更新