React 中使用示例
在 react 中,这里的 useMemo 是必须要使用的,避免组件渲染的时候,重新创建 uploader 对象
直接使用
tsx
import React, { useState, useMemo } from "react";
import { createUploader } from "enlarge-file-upload";
import type { Config, UploadOptions } from "enlarge-file-upload";
import axios from "axios";
const FileUpload = () => {
const [progress, setProgress] = useState(0);
const [speed, setSpeed] = useState("0 MB/s");
// 定义上传函数
async function uploadFunction({
chunk,
index,
hash,
cancelToken,
}: UploadOptions) {
const formData = new FormData();
formData.append("chunk", chunk);
formData.append("hash", hash);
formData.append("index", index);
await axios.post("http://xxxx/api/upload", formData, {
cancelToken,
});
}
const uploaderConfig: Config = useMemo(
() => ({
chunkSize: 5 * 1024 * 1024, // 5MB
concurrency: 5,
maxRetries: 3,
// startOffset: 6, // 从索引为10的切片位置开始传
// includeChunks:[1,6], // 只上传索引为1和6的切片,只有startOffset为0或空时才生效
uploadFunction,
onProgress: (progress) => {
setProgress(progress);
},
onSuccess: () => {
console.log("上传完毕");
},
onSpeed: (speed) => {
setSpeed(speed);
},
}),
[]
);
const uploader = useMemo(
() => createUploader(uploaderConfig),
[uploaderConfig]
);
const handleFileChange = (event) => {
const file = event.target.files[0];
uploader?.upload(file);
};
const handlePause = () => {
uploader?.pause();
};
const handleResume = () => {
uploader?.resume();
};
return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={handlePause}>暂停上传</button>
<button onClick={handleResume}>继续上传</button>
<div>上传进度:{progress.toFixed(2)}%</div>
<div>上传速度:{speed}</div>
</div>
);
};
export default FileUpload;
封装为 react Hooks
一个简单的封装,如有特殊需求,可以基于这个 hooks 进行二次修改
tsx
import { useState, useMemo, useCallback } from "react";
import { createUploader } from "enlarge-file-upload";
import type { Config, UploadOptions } from "enlarge-file-upload";
import axios from "axios";
const useFileUploader = () => {
const [progress, setProgress] = useState(0);
const [speed, setSpeed] = useState("0 MB/s");
const uploadFunction = useCallback(
async ({ chunk, index, hash, cancelToken }: UploadOptions) => {
const formData = new FormData();
formData.append("chunk", chunk);
formData.append("hash", hash);
formData.append("index", index);
await axios.post("http://xxxx/api/upload", formData, {
cancelToken,
});
},
[]
);
const uploaderConfig: Config = useMemo(
() => ({
chunkSize: 5 * 1024 * 1024, // 5MB
concurrency: 5,
maxRetries: 3,
// startOffset: 6, // 从索引为10的切片位置开始传
// includeChunks:[1,6], // 只上传索引为1和6的切片,只有startOffset为0或空时才生效
uploadFunction,
onProgress: (progress) => {
setProgress(progress);
},
onSuccess: () => {
console.log("Upload complete");
},
onSpeed: (speed) => {
setSpeed(speed);
},
}),
[uploadFunction]
);
const uploader = useMemo(
() => createUploader(uploaderConfig),
[uploaderConfig]
);
const uploadFile = useCallback(
(file) => {
uploader?.upload(file);
},
[uploader]
);
const pauseUpload = useCallback(() => {
uploader?.pause();
}, [uploader]);
const resumeUpload = useCallback(() => {
uploader?.resume();
}, [uploader]);
return {
progress,
speed,
uploadFile,
pauseUpload,
resumeUpload,
};
};
export default useFileUploader;
使用封装好的 Hooks 示例
tsx
import React from "react";
import useFileUploader from "./useFileUploader.tsx";
const FileUpload = () => {
const { progress, speed, uploadFile, pauseUpload, resumeUpload } =
useFileUploader();
const handleFileChange = (event) => {
const file = event.target.files[0];
uploadFile(file);
};
return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={pauseUpload}>Pause Upload</button>
<button onClick={resumeUpload}>Resume Upload</button>
<div>Upload Progress: {progress.toFixed(2)}%</div>
<div>Upload Speed: {speed}</div>
</div>
);
};
export default FileUpload;