React Native 0.70.4新架构下fetch()功能异常求助
React Native 0.70.4新架构下fetch()失效问题排查
问题场景
- 环境:React Native 0.70.4(启用新架构)、TypeScript、ES模块导入配置
- 原生
fetch()异常表现:- 调用时控制台输出错误:
'Tried to call timer with ID %s but no such timer exists.', 6 - 点击测试按钮后仅打印
PRESSED,无后续res/err日志,Flipper网络面板无请求记录
- 调用时控制台输出错误:
- 使用
cross-fetch后的异常表现:- 控制台打印
PRESSED和promise: { _h: 0, _i: 0, _j: null, _k: null },但无后续日志 - Flipper显示请求已成功完成,但代码中
await后的逻辑未执行
- 控制台打印
可能原因及解决方法
1. 新架构Timer模块与ES模块兼容性冲突
RN 0.70.x新架构在ES模块模式下,Timer系统的初始化逻辑可能和全局fetch的依赖链冲突。原生fetch依赖RN的Timer调度异步回调,一旦Timer模块出现异常,会导致fetch的Promise无法正常resolve/reject。
解决步骤:
- 检查
metro.config.js的ES模块配置,确保react-native核心模块的导出被正确解析:module.exports = { resolver: { unstable_enablePackageExports: true, extraNodeModules: require('node-libs-react-native'), }, }; - 临时切换到CommonJS兼容模式测试,修改
babel.config.js:module.exports = { presets: ['module:metro-react-native-babel-preset'], plugins: [ ['@babel/plugin-transform-modules-commonjs', { allowTopLevelThis: true }], ], };
2. 全局fetch未被正确注入
新架构下,全局fetch的注入逻辑可能因TS配置或ES模块导入顺序问题未执行。RN原生fetch通过react-native/Libraries/Fetch/fetch.js注入全局,若该文件未被加载,就会出现fetch失效。
解决步骤:
- 在项目入口文件(如
index.tsx)手动导入并挂载全局fetch:import { fetch } from 'react-native'; global.fetch = fetch; - 调整
tsconfig.json的模块解析配置,避免ES模块解析错误:{ "compilerOptions": { "moduleResolution": "node", "allowSyntheticDefaultImports": true, "esModuleInterop": true } }
3. Flipper与新架构的日志捕获冲突
使用cross-fetch时请求实际成功但无后续日志,可能是Flipper的网络拦截干扰了Promise回调的执行,或是RN新架构的日志系统对异步日志处理存在延迟。
解决步骤:
- 关闭Flipper,直接查看原生日志(Android用Logcat,iOS用Console.app),确认
res/err是否真的未输出 - 在
await后添加setTimeout强制刷新日志队列:try { const res = await promise; setTimeout(() => console.log('res:', res), 0); } catch (err: unknown) { setTimeout(() => console.log('err:', err), 0); }
4. RN 0.70.4新架构已知Bug
RN 0.70.x新架构存在部分未修复的兼容性问题,Timer与fetch的冲突属于小概率已知问题,后续版本已修复。
解决步骤:
- 升级React Native到0.71.x及以上版本,新架构稳定性在后续版本有显著提升
- 若暂时无法升级,可临时禁用新架构的Timer优化(仅作测试,不建议长期使用),修改
android/app/src/main/java/com/[你的应用包名]/MainApplication.java:@Override protected ReactNativeHost getReactNativeHost() { return new ReactNativeHost(this) { // 保留原有配置... @Override protected ReactInstanceManager createReactInstanceManager() { ReactInstanceManager.Builder builder = ReactInstanceManager.builder() .setApplication(getApplication()) .setJSMainModulePath(getJSMainModuleName()) .addPackages(getPackages()) .setUseDeveloperSupport(getUseDeveloperSupport()) .setInitialLifecycleState(LifecycleState.RESUMED); // 临时回退到老桥接模式的Timer实现 builder.setUseOldBridge(true); return builder.build(); } }; }
内容的提问来源于stack exchange,提问作者nerdlinger
相关产品推荐
相关产品推荐

