You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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(仅开发环境适用)

  1. 修改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);
          };
        },
      },
    });
    
  2. 复制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文件名列表,或打包时自动生成:

  1. 创建assetsList.js文件导出文件名:
    export const imageFiles = [
      'image1.png',
      'image2.jpg',
      'image3.jpeg',
      // 列出assets/images下所有文件名
    ];
    
  2. 在组件中直接使用:
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 20:51:13