跳到主要内容

useFile

信息

新版本的useFile新增了相关事件的参数配置. 但和小程序中的事件略有出入. 由于taro-hooks采用的是Promise的方式编写. 这边事件名称分别

useFile

上传、下载文件

何时使用

当需要上传下载文件时

API

const { download, upload } = useFile();

返回值说明

返回值说明类型
download下载文件PromiseAction<DownloadOption, Taro.downloadFile.FileSuccessCallbackResult>
upload上传文件PromiseAction<UploadOption, Taro.uploadFile.SuccessCallbackResult>

DownloadOption

参数说明类型默认值
url下载资源的 urlstring-
filePath指定文件下载后存储的路径string-
headerHTTP 请求的 Header,Header 中不能设置 RefererTaroGeneral.IAnyObject-
progress监听下载进度变化事件DownloadTask['onProgressUpdate']-
headersReceive监听 HTTP Response Header 事件。会比请求完成事件更早DownloadTask['onHeadersReceived']-
afterSend实例后挂载对应监听方法(task: DownloadTask.DownloadTaskPromise) => void-

UploadOption

参数说明类型默认值
url开发者服务器地址string-
filePath要上传文件资源的路径string-
name文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容string-
formDataHTTP 请求中其他额外的 form dataTaroGeneral.IAnyObject-
timeout超时时间,单位为毫秒number-
headerHTTP 请求的 Header,Header 中不能设置 RefererTaroGeneral.IAnyObject-
fileName上传的文件名, API 支持度: h5string-
progress监听下载进度变化事件UploadTask['onProgressUpdate']-
headersReceive监听 HTTP Response Header 事件。会比请求完成事件更早UploadTask['onHeadersReceived']-
afterSend实例后挂载对应监听方法(task: UploadTask.UploadTaskPromise) => void-

代码演示

network/useFile/index
import React from 'react';
import { showToast, showModal, chooseVideo } from '@tarojs/taro';
import { useState } from '@taro-hooks/core';
import { log, logError } from '@taro-hooks/shared';
import { useFile } from 'taro-hooks';
import DemoContent from '@src/components/DemoContent';
import { Cell, Button, Progress, Input, Field } from '@taroify/core';

export default () => {
const [loading, setLoading] = useState<boolean>(false);
const [uploadProgress, setUploadProgress] = useState<number>(0);
const [downloadFile, setDownloadFile] = useState<string>(
'https://storage.360buyimg.com/nutui/video/video_NutUI.mp4',
);
const [downloadProgress, setDownloadProgress] = useState<number>(0);

const { download, upload } = useFile();

const onProgress = (
{ progress = 0, totalBytesSent = 0, totalBytesExpectedToSend = 0 } = {},
action,
) => {
action(progress);
showToast({
title: '${progress}%: ${totalBytesSent} / ${totalBytesExpectedToSend}',
icon: 'loading',
mask: true,
});
};

const onHeadersReceived = (headers) => {
log(headers);
showToast({
title: 'onHeadersReceived trigger',
icon: 'none',
mask: true,
});
};

const handleDownload = async () => {
if (!downloadFile?.length) return;
const downloadUpdate = (progressResult) =>
onProgress(progressResult, setDownloadProgress);
const option = {
progress: downloadUpdate,
headersReceive: onHeadersReceived,
url: downloadFile,
};
setLoading(true);
setDownloadProgress(0);
try {
const response = await download(option);
showModal({
title: '下载成功',
content: response?.tempFilePath,
showCancel: false,
});
} catch (e) {
logError(e.message);
}
setLoading(false);
};

const handleUpload = async () => {
try {
const videos = await chooseVideo({});
if (videos?.tempFilePath) {
setUploadProgress(0);
setLoading(true);
const uploadUpdate = (progressResult) =>
onProgress(progressResult, setUploadProgress);
const option = {
progress: uploadUpdate,
headersReceive: onHeadersReceived,
filePath: videos.tempFilePath,
};
const response = await upload(option);
showModal({
title: '上传成功',
content: response?.data,
showCancel: false,
});
}
} catch (e) {
logError(e.message);
}
setLoading(false);
};

return (
<DemoContent>
<Cell title="上传" clickable>
<Button loading={loading} onClick={handleUpload}>
点击
</Button>
</Cell>
<Progress percent={uploadProgress} />
<Field label="地址">
<Input
value={downloadFile}
onChange={(event) => setDownloadFile(event.detail.value)}
placeholder="请输入下载地址"
/>
</Field>
<Cell title="下载" clickable>
<Button loading={loading} onClick={handleDownload}>
点击
</Button>
</Cell>
<Progress percent={downloadProgress} />
</DemoContent>
);
};

Hook 支持度

微信小程序H5ReactNative
✔️✔️✔️

FAQ

  1. 如何abort下载或上传?

    可以使用afterSend监听方法获取到xxxTask.xxxTaskPromise.

    import { useRef } from '@tarojs/taro';

    const task = useRef<UploadTask.UploadTaskPromise>();

    const afterSend = (concurrentTask) => (task.current = concurrentTask);

    // then

    task.current.abort();