react-native-http-cache 使用

本文介绍了如何在React Native项目中安装和使用react-native-http-cache库进行HTTP缓存管理。首先通过npm安装并使用react-native link关联库。在iOS端,库会自动添加依赖。接着,在代码中引入库并学习如何获取或清除缓存。在实施过程中,可能会遇到WebStorm运行报错和Android运行报错的问题,文中提供了相应的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:安装

下载:npm install react-native-http-cache --save

关联:react-native link react-native-http-cache

二:使用

在关联成功之后,ios这边会自动添加依赖 libRCTHttpCache.a

首先在使用的类文件中引入

import * as CacheManager from 'react-native-http-cache'

获取/清除

    // 获得缓存大小
    async getCacheSize() {
        const data = await CacheManager.getCacheSize();
        const size = data / (1024 * 1024);
        this.setState({ cacheSize: size.toFixed(2) + 'M'});
    }
    // 清除缓存
    async clearCacheSize() {
        await CacheManager.clearCache();
        // 这里貌似清除不能全部清除为0,这里直接写死0即可。
        this.setState({cacheSize: '0M'});
        Tips.show('清除缓存成功');
    }

三、遇到的问题

   1)在引入之后,webStorm运行会报错Cannot read property 'clearCache' of undefined,用xcode打开显示错误是

(此图摘自点击这里,非常感谢)

 原因是重复导入,修改办法注释掉图中那三个

(此图摘自点击这里,非常感谢)

2)运行安卓时会报如下错

解决办法:将下列代码覆盖掉Android下的 HttpCacheModule.java文件

package cn.reactnative.httpcache;
 
import android.content.Intent;
 
import com.facebook.cache.disk.DiskStorageCache;
import com.facebook.cache.disk.FileCache;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipelineFactory;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.modules.network.OkHttpClientProvider;
import okhttp3.Cache;
 
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
 
/**
 * Created by tdzl2_000 on 2015-10-10.
 */
public class HttpCacheModule extends ReactContextBaseJavaModule {
    public HttpCacheModule(ReactApplicationContext context) {
        super(context);
    }
 
    @Override
    public String getName() {
        return "RCTHttpCache";
    }
 
    @ReactMethod
    public void clearCache(Promise promise){
        try {
            Cache cache = OkHttpClientProvider.getOkHttpClient().cache();
            if (cache != null) {
                cache.delete();
            }
            promise.resolve(null);
        } catch(IOException e){
            promise.reject(e);
        }
    }
 
    @ReactMethod
    public void getHttpCacheSize(Promise promise){
        try {
            Cache cache = OkHttpClientProvider.getOkHttpClient().cache();
            promise.resolve(cache != null ? ((double)cache.size()) : 0);
        } catch(IOException e){
            promise.reject(e);
        }
    }
 
    static Method update;
    private void updateCacheSize(DiskStorageCache cache) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        if (update == null){
            update = DiskStorageCache.class.getDeclaredMethod("maybeUpdateFileCacheSize");
            update.setAccessible(true);
        }
        update.invoke(cache);
    }
 
    @ReactMethod
    public void getImageCacheSize(Promise promise){
        FileCache cache1 = ImagePipelineFactory.getInstance().getMainFileCache();
        long size1 = cache1.getSize();
        if (size1 < 0){
            try {
                updateCacheSize((DiskStorageCache)cache1);
            } catch (Exception e){
                promise.reject(e);
                return;
            }
            size1 = cache1.getSize();
        }
        FileCache cache2 = ImagePipelineFactory.getInstance().getSmallImageFileCache();
        long size2 = cache2.getSize();
        if (size2 < 0){
            try {
                updateCacheSize((DiskStorageCache)cache2);
            } catch (Exception e){
                promise.reject(e);
                return;
            }
            size2 = cache2.getSize();
        }
        promise.resolve(((double)(size1+size2)));
    }
 
    @ReactMethod
    public void clearImageCache(Promise promise){
        FileCache cache1 = ImagePipelineFactory.getInstance().getMainFileCache();
        cache1.clearAll();
        FileCache cache2 = ImagePipelineFactory.getInstance().getSmallImageFileCache();
        cache2.clearAll();
        promise.resolve(null);
    }
}

 

D:\AwesomeProject>npm ls react AwesomeProject@0.0.1 D:\AwesomeProject +-- @ant-design/icons-react-native@2.3.2 | `-- react@17.0.2 deduped +-- @ant-design/react-native@5.4.2 | +-- @floating-ui/react-native@0.10.7 | | `-- react@17.0.2 deduped | +-- rc-field-form@2.7.0 | | `-- react@17.0.2 deduped | +-- rc-util@5.44.4 | | `-- react@17.0.2 deduped | +-- react-native-collapsible@1.6.2 | | `-- react@17.0.2 deduped | +-- react-native-modal-popover@2.1.3 | | `-- react@17.0.2 deduped | `-- react@17.0.2 deduped +-- @react-native-community/cameraroll@4.1.2 | `-- react@17.0.2 deduped +-- @react-native-community/masked-view@0.1.11 | `-- react@17.0.2 deduped +-- @react-native-community/segmented-control@2.2.2 | `-- react@17.0.2 deduped +-- @react-native-community/slider@3.0.3 | `-- react@17.0.2 deduped +-- @react-native-community/viewpager@4.2.4 | `-- react@17.0.2 deduped +-- @react-native-picker/picker@1.16.8 | `-- react@17.0.2 deduped +-- @react-navigation/native-stack@6.11.0 | +-- @react-navigation/elements@1.3.31 | | `-- react@17.0.2 deduped | `-- react@17.0.2 deduped +-- @react-navigation/native@6.1.18 | +-- @react-navigation/core@6.4.17 | | +-- react@17.0.2 deduped | | `-- use-latest-callback@0.2.4 | | `-- react@17.0.2 deduped invalid: "^16.0.0" from node_modules/react-native-elements/node_modules/react-native-ratings | `-- react@17.0.2 deduped +-- @rneui/base@4.0.0-rc.8 | `-- react-native-ratings@8.1.0 | `-- react@17.0.2 deduped +-- react-native-elements@1.2.7 | `-- react-native-ratings@6.5.0 | `-- react@17.0.2 deduped invalid: "^16.0.0" from node_modules/react-native-elements/node_modules/react-native-ratings +-- react-native-exception-handler@2.10.10 | `-- react@17.0.2 deduped +-- react-native-image-picker@3.8.1 | `-- react@17.0.2 deduped +-- react-native-image-zoom-viewer@3.0.1 | +-- react-native-image-pan-zoom@2.1.12 | | `-- react@17.0.2 deduped invalid: "^16.0.0" from node_modules/react-native-elements/node_modules/react-native-ratings | `-- react@17.0.2 deduped +-- react-native-linear-gradient@2.8.3 | `-- react@17.0.2 deduped +-- react-native-permissions@3.8.0 | `-- react@17.0.2 deduped +-- react-native-reanimated@2.14.4 invalid: ">=3.10.1" from node_modules/@ant-design/react-native | `-- react@17.0.2 deduped +-- react-native-safe-area-context@3.3.2 | `-- react@17.0.2 deduped +-- react-native-screens@3.15.0 | +-- react-freeze@1.0.4 | | `-- react@17.0.2 deduped invalid: "^16.0.0" from node_modules/react-native-elements/node_modules/react-native-ratings | `-- react@17.0.2 deduped +-- react-native-svg-charts@5.4.0 | `-- react@17.0.2 deduped +-- react-native-webview@11.26.1 | `-- react@17.0.2 deduped +-- react-native@0.68.0 | +-- react-shallow-renderer@16.14.1 | | `-- react@17.0.2 deduped invalid: "^16.0.0" from node_modules/react-native-elements/node_modules/react-native-ratings | +-- react@17.0.2 deduped | `-- use-subscription@1.11.0 | +-- react@17.0.2 deduped invalid: "^16.0.0" from node_modules/react-native-elements/node_modules/react-native-ratings | `-- use-sync-external-store@1.5.0 | `-- react@17.0.2 deduped invalid: "^16.0.0" from node_modules/react-native-elements/node_modules/react-native-ratings +-- react-redux@7.2.9 | `-- react@17.0.2 deduped +-- react-test-renderer@17.0.2 | `-- react@17.0.2 deduped `-- react@17.0.2 npm error code ELSPROBLEMS npm error invalid: react@17.0.2 D:\AwesomeProject\node_modules\react npm error A complete log of this run can be found in: C:\Users\临时\AppData\Local\npm-cache\_logs\2025-08-01T01_11_42_653Z-debug-0.log
最新发布
08-02
<think>好的,我现在需要分析用户提供的`npm ls react`输出,找出可能导致React Hooks错误的原因。首先,用户之前遇到了“Invalid hook call”错误,这通常与React版本不一致或多个实例有关。 首先看用户的依赖树,最顶层的`react`版本是17.0.2,大部分依赖都标记了`deduped`(去重),说明它们共享了顶层的React实例。但注意到有几个依赖项标记了`invalid`,例如: - `node_modules/react-native-elements/node_modules/react-native-ratings`中要求`react@^16.0.0`,但实际使用的是17.0.2。 - `react-native-image-pan-zoom`、`react-freeze`、`react-shallow-renderer`、`use-subscription`、`use-sync-external-store`等依赖也有类似的`invalid`提示,都是因为它们的`peerDependencies`要求React版本为16.x,但项目中实际用了17.0.2。 另外,还有一个更严重的问题:`react-native-reanimated`标记为`invalid`,因为`@ant-design/react-native`要求它的版本`>=3.10.1`,但用户安装的是2.14.4,版本不匹配。 这些版本冲突可能导致React实例不一致或依赖解析错误,从而引发Hooks调用异常。具体来说: 1. **Peer Dependency 不兼容**:部分依赖(如`react-native-ratings`)的`peerDependencies`要求React 16.x,但项目使用React 17.x,虽然npm/yarn可能允许安装,但可能导致运行时问题,因为这些库可能未完全兼容React 17的Hooks机制。 2. **react-native-reanimated 版本不匹配**:`@ant-design/react-native`需要`react-native-reanimated >=3.10.1`,但用户安装了2.14.4,这可能导致该库无法正确初始化,进而影响React Native的AppRegistry注册,引发第二个错误(“Module AppRegistry is not registered”)。 3. **依赖解析混乱**:尽管大部分依赖共享了顶层的React 17.0.2,但部分子依赖的`invalid`标记可能导致npm在解析时生成不一致的模块树,可能间接导致React实例被多次加载(例如某些库可能尝试从自己的`node_modules`中引入React)。 解决步骤应针对这些具体的版本冲突: - **升级 react-native-reanimated 到符合要求的版本**(>=3.10.1),以满足`@ant-design/react-native`的依赖需求。 - **处理 react-native-ratings 等库的React版本不兼容**:检查`react-native-elements`和`react-native-ratings`的版本是否有支持React 17的更新版本,或者考虑替换为其他兼容的组件库。 - **清理并重新安装依赖**:删除`node_modules`和锁文件,重新安装以确保依赖解析正确。 - **检查 peerDependencies 警告**:安装时注意npm/yarn的警告信息,手动安装符合要求的peer依赖(如果必要)。 </think>根据你提供的`npm ls react`输出,问题主要集中在**依赖版本冲突**和**Peer Dependency 不兼容**,这是导致“Invalid hook call”和“AppRegistry未注册”错误的核心原因。以下是具体分析和解决方法: ### 一、关键问题定位 从依赖树可以看到两个核心冲突: #### 1. `react-native-reanimated` 版本不匹配 `@ant-design/react-native` 要求 `react-native-reanimated >=3.10.1`,但你当前安装的是 `2.14.4`(标记为`invalid`)。 这会导致 `@ant-design/react-native` 无法正常初始化,可能引发React Native核心模块(如AppRegistry)加载失败,从而出现“Module AppRegistry is not registered”错误。 #### 2. 多个依赖的 Peer Dependency 与 React 17 不兼容 例如: - `react-native-ratings`(来自`react-native-elements`)要求 `react@^16.0.0`,但实际使用 `17.0.2`(标记为`invalid`); - `react-freeze`、`react-shallow-renderer`等依赖也存在类似的React 16.x 版本要求,但项目用了React 17.x。 虽然npm允许安装不兼容的Peer Dependency,但这些库可能未完全适配React 17的Hooks机制,导致Hooks调用上下文异常,引发“Invalid hook call”错误。 ### 二、解决步骤 #### 1. 修复 `react-native-reanimated` 版本冲突 `@ant-design/react-native` 需要 `react-native-reanimated >=3.10.1`,而React Native 0.68.x 兼容的 `react-native-reanimated` 最新版本是 **3.x**(需确认兼容性)。 **操作步骤**: ```bash # 卸载旧版本 npm uninstall react-native-reanimated # 安装兼容React Native 0.68.x的最新3.x版本(例如3.3.0,具体版本需查官方文档) npm install react-native-reanimated@3.3.0 ``` #### 2. 解决 `react-native-ratings` 等库的React版本不兼容 `react-native-ratings` 6.5.0(来自`react-native-elements@1.2.7`)仅支持React 16.x,而你使用React 17.x。 **解决方案**: - **升级 `react-native-elements` 到更高版本**:新版本可能已修复Peer Dependency问题。例如,`react-native-elements@4.x` 可能支持React 17/18。 执行:`npm install react-native-elements@latest`(注意检查是否兼容React Native 0.68.x)。 - **替换为其他组件库**:如果升级后仍有问题,考虑使用其他兼容React 17的评分组件(如`react-native-star-rating`)。 #### 3. 清理依赖并重新安装 版本冲突可能导致缓存残留,需彻底清理后重新安装: ```bash # 删除依赖和锁文件 rm -rf node_modules package-lock.json # 重新安装 npm install ``` #### 4. 验证依赖一致性 重新安装后,再次运行 `npm ls react`,确认所有`invalid`标记消失,且所有依赖指向同一React 17.0.2实例。 ### 三、额外注意事项 - **React Native 0.68.x 兼容版本**:确保所有依赖(如`@ant-design/react-native`)兼容React Native 0.68.x。例如,`@ant-design/react-native@5.4.2` 是否支持0.68.x需查看官方文档。 - **Hooks 调用检查**:即使依赖修复,仍需确认代码中Hooks是否在函数组件顶层调用(无循环/条件/类组件中调用)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值