news 2026/8/24 22:03:23

React Native 文件选择实战:react-native-document-picker 从选文件到另存为的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
React Native 文件选择实战:react-native-document-picker 从选文件到另存为的完整指南

React Native 文件选择实战:react-native-document-picker 从选文件到另存为的完整指南

【免费下载链接】react-native-document-pickerDocument Picker and Viewer for React Native项目地址: https://gitcode.com/gh_mirrors/re/react-native-document-picker

做个"导入 PDF 合同"功能时,90% 的坑不在 UI,而在拿到那个文件 URI 之后:有的 URI 是临时授权、App 一杀进程就读不到了;有的文件是 Google Docs 这种"虚拟文件",根本没有实体;还有个平台的文件管理器压根不遵守你的类型过滤。react-native-document-picker(包名@react-native-documents/picker)封装了 iOS 的 UIDocumentPicker 和 Android 的 Storage Access Framework,把文件选择、类型过滤、多选、另存为、长期访问权限这几件事统一成一套 JS API。

30 秒接入:装包 + 第一次 pick

yarn add @react-native-documents/picker

iOS 项目装完在ios/目录执行pod install,Android 无需额外配置。Expo 项目不能跑在 Expo Go 里(含自定义原生代码),需要走expo prebuild --clean打开发构建。

然后是最小可用的选择逻辑:

import DocumentPicker from '@react-native-documents/picker' const onPick = async () => { try { const res = await DocumentPicker.pick() // 不传 type = 全部文件 console.log(res[0].uri, res[0].name, res[0].size) } catch (err) { if (DocumentPicker.isCancel(err)) return // 用户点了取消,不算错误 console.error(err) } }

注意两点:结果总是数组(哪怕只选了一个);用户取消会走 reject,所以必须 catch 并用isCancel区分"取消"和"真报错"。

场景一:只收 PDF,但别全信文件管理器

合同上传、简历投递这类场景要限定类型。库内置了常用 MIME/UTI 常量(Android 映射为 MIME,iOS 映射为 UTType,一套代码双端自动切换):

await DocumentPicker.pick({ type: [DocumentPicker.types.pdf], })

全部预定义常量(pdfimagesvideodocxxlsxallFiles…)在packages/document-picker/src/fileTypes.ts,也可以直接传任意字符串。

坑:Android 上部分第三方文档提供者会无视类型过滤,用户仍能挑一个 .docx 出来。响应里的hasRequestedType字段为false时说明用户挑的文件不在你要的类型里,这种情况自己做二次校验并提示用户,别默默收下。

场景二:批量导入素材,一次挑 N 个

图片编辑、素材库应用需要用户一次挑几十张图,加一个开关即可:

const res = await DocumentPicker.pick({ type: [DocumentPicker.types.images], allowMultiSelection: true, }) res.forEach(f => console.log(f.uri, f.size))

每个元素都是完整的元数据对象:urinametypesizenativeType,直接拿来建索引,不用再逐个读文件。

场景三:把生成的文件另存到用户目录

上传完文件,反过来还要"写出去"——比如把导出的报告存到用户的 Documents。saveDocuments会拉起系统的"另存为"对话框,让用户自己挑位置:

const res = await DocumentPicker.saveDocuments({ sourceUris: [reportUri], fileName: '2026-Q2-报告.pdf', // Android 端预填文件名 })

平台差异记住一句话就够:Android 一次只能存 1 个文件,iOS 可以多存fileName只在 Android 生效(iOS 的名字取自源文件,仅单文件时用户可改);mimeType也是 Android 专用,建议提供,省得系统去猜。

import 还是 open:文件生命周期怎么选

这是最容易踩错的地方,直接给结论:

模式行为适用场景
mode: 'import'(默认)文件复制到 App 沙盒,长期可读可上传上传服务器、离线缓存
mode: 'open'临时授权,App 被杀后失效只读预览一次
mode: 'open'+requestLongTermAccess: true返回bookmark,重启后凭它重新访问需要跨启动访问同一文件

三个模式的行为对比见下图,限制为 PDF 的导入模式:

另外两个配套 API:

  • keepLocalCopy:把content://URI 或虚拟文件(Google Docs 之类)导出成沙盒里的实体文件,目标目录可选cachesDirectory/documentDirectory。上传场景其实用不到它——fetch直接支持content://URI,能省一步省一步。
  • pickDirectory:选文件夹而不是文件,同样支持短期/长期授权。

双端配置清单:好消息是基本不用配

项目AndroidiOS
运行时存储权限不需要(走 SAF,无需 READ/WRITE_EXTERNAL_STORAGE)不需要
Info.plist 描述文案不需要(系统选择器自带授权流)
额外依赖pod install
虚拟文件(云文档)allowVirtualFiles: true开启,响应带isVirtualconvertibleToMimeTypes无此概念

很多旧教程让你加存储权限、改requestLegacyExternalStorage,那是 SAF 之前的做法,现在加只会惹审计麻烦。

真正的平台差异集中在响应字段:Android 的uricontent://,iOS 是file://nativeType在 Android 是 MIME、在 iOS 是 UTI。跨端逻辑只认uri+type,别碰平台私有字段。

报错对照表:四种 code 各是什么情况

catch (err) { if (DocumentPicker.isErrorWithCode(err)) { switch (err.code) { case DocumentPicker.errorCodes.OPERATION_CANCELED: // 用户取消 case DocumentPicker.errorCodes.IN_PROGRESS: // 已有选择器在弹 case DocumentPicker.errorCodes.UNABLE_TO_OPEN_FILE_TYPE: // 类型无法解析 case DocumentPicker.errorCodes.NULL_PRESENTER: // 无可用 UI 上下文 } } }
  • 取消(OPERATION_CANCELED):静默处理,不要弹错误提示。
  • IN_PROGRESS:按钮防抖,或选择器还没关就再次点击了。
  • UNABLE_TO_OPEN_FILE_TYPE:检查传给type的字符串是不是合法的 MIME/UTI。

上手就干三件事

先跑通pick()+isCancel这条最小链路,再按你的业务挑一条线深入:要传服务器走 import 模式,要长期引用换 long-term access,要写出去用saveDocuments。完整参数表在 安装与配置文档,原生实现参考 Android 模块源码 和 iOS 模块源码。

【免费下载链接】react-native-document-pickerDocument Picker and Viewer for React Native项目地址: https://gitcode.com/gh_mirrors/re/react-native-document-picker

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/24 21:59:34

OpenArm:一副6500美元的7自由度开源协作机械臂是怎么做到的

OpenArm:一副6500美元的7自由度开源协作机械臂是怎么做到的 【免费下载链接】openarm A fully open-source humanoid arm for physical AI research and deployment in contact-rich environments. 项目地址: https://gitcode.com/GitHub_Trending/op/openarm …

作者头像 李华
网站建设 2026/8/24 21:59:19

DBeaver 崩溃后 5 分钟找回 SQL 脚本:完整指南

DBeaver 崩溃后 5 分钟找回 SQL 脚本:完整指南 【免费下载链接】dbeaver Free universal database tool and SQL client 项目地址: https://gitcode.com/GitHub_Trending/db/dbeaver DBeaver 崩溃后,最怕的就是没保存的 SQL 脚本找不回来。这篇文…

作者头像 李华
网站建设 2026/8/24 21:53:54

「AI 应用 / AI Agent」行业日报 · 2026-08-23

「AI 应用 / AI Agent」行业日报 2026-08-23 📊 市场信号 阿里巴巴发布2027财年Q1财报,营收2690亿元,同期宣布新一轮业务架构调整:电商合并、云芯片整合、千问分拆为独立子公司 [数据来源:36氪《9点1氪》;…

作者头像 李华
网站建设 2026/8/24 21:51:09

Linux命令合集

ls查看当前目录下文件的相关信息cd .跳转当前目录cd ..跳转到上级目录pwd查看当前目录的绝对路径whoami可以查看当前登录的用户名su root可以切换到管理员which查找外部命令路径whereis查找命令的二进制、源码、手册页type显示命令类型(内置/外部/别名)c…

作者头像 李华
网站建设 2026/8/24 21:44:37

UMA:毫秒级预测能量与力,一个模型跑通材料与分子动力学

UMA:毫秒级预测能量与力,一个模型跑通材料与分子动力学 【免费下载链接】ocp FAIR Chemistrys library of machine learning methods for chemistry 项目地址: https://gitcode.com/GitHub_Trending/oc/ocp 给吸附在 Cu(100) 表面上的 CO 做结构…

作者头像 李华