React Native读取文件名报错:new NativeEventEmitter()需非空参数
解决React Native读取文件名的问题
第一步:修复NativeEventEmitter错误
这个错误源于react-native-fs的原生模块未正确注册,按以下步骤处理:
- 若使用RN 0.60+版本,先卸载重装依赖触发自动链接:
npm uninstall react-native-fs npm install react-native-fs - 自动链接失败时手动执行链接:
npx react-native link react-native-fs - 清理缓存并重启项目:
npx react-native start --reset-cache cd ios && pod install && cd .. npx react-native run-android # 对应iOS则执行 npx react-native run-ios - 版本兼容检查:RN 0.70+需确保react-native-fs为最新稳定版(如>=2.20.0),旧版本不兼容新RN的EventEmitter API。
第二步:正确读取assets目录下的文件
你使用的../assets/images是源码相对路径,但RN打包后assets会嵌入应用包,并非文件系统可直接访问的目录,react-native-fs无法直接读取该路径,推荐两种可行方案:
方案1:Metro配置暴露assets(仅开发环境适用)
- 修改
metro.config.js,添加asset后缀与路径映射:const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); const config = {}; module.exports = mergeConfig(getDefaultConfig(__dirname), { resolver: { assetExts: ['png', 'jpg', 'jpeg', 'gif'], // 添加上你需要读取的图片后缀 }, server: { enhanceMiddleware: (middleware) => { return (req, res, next) => { if (req.url.startsWith('/assets/')) { req.url = req.url.replace('/assets/', '/'); } return middleware(req, res, next); }; }, }, }); - 复制assets到可访问目录后读取:
import React, {useEffect, useState} from 'react'; import {View, Text} from 'react-native'; import RNFS from 'react-native-fs'; export default function mainScreen({navigation}) { const [fileNames, setFileNames] = useState([]); useEffect(() => { const copyAndReadAssets = async () => { const sourceDir = RNFS.MainBundlePath + '/assets/images'; const targetDir = RNFS.DocumentDirectoryPath + '/images'; // 确保目标目录存在 await RNFS.mkdir(targetDir).catch(() => {}); // 复制assets到可访问目录 await RNFS.copyFile(sourceDir, targetDir).catch(err => console.log('复制失败:', err)); // 读取文件列表 const files = await RNFS.readdir(targetDir); setFileNames(files); }; copyAndReadAssets(); }, []); return ( <View> {fileNames.map((name, idx) => ( <Text key={idx}>{name}</Text> ))} </View> ); }
方案2:预定义assets文件列表(生产环境推荐)
直接在代码中维护assets文件名列表,或打包时自动生成:
- 创建
assetsList.js文件导出文件名:export const imageFiles = [ 'image1.png', 'image2.jpg', 'image3.jpeg', // 列出assets/images下所有文件名 ]; - 在组件中直接使用:
import {imageFiles} from './assetsList'; export default function mainScreen({navigation}) { return ( <View> {imageFiles.map((name, idx) => ( <Text key={idx}>{name}</Text> ))} </View> ); }
这种方式稳定性更高,因为RN打包后assets不会暴露文件系统路径,预定义列表是生产环境最可靠的读取方式。
额外注意事项
- 不要使用相对路径
../assets/images,RN的assets在原生端路径因平台而异(Android为res/drawable,iOS为Assets.xcassets),无法通过文件系统直接读取。 - 开发环境可临时使用react-native-fs的
bundleResourcePath,但生产环境必须采用预定义列表或预打包处理。
内容的提问来源于stack exchange,提问作者Tim Bretschneider
相关产品推荐
相关产品推荐

