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

React Native如何创建全局状态?解决收藏夹点击后页面不重渲染问题

问题核心原因

  • 直接突变了来自StorageContext的storageDB对象:React 依赖状态引用变化判断是否触发重渲染,你直接修改原对象的favorite属性,storageDB的引用没有变更,所有监听它的组件/钩子都感知不到更新
  • useStorage中获取收藏列表的逻辑只在钩子初始化时执行一次,没有和全局的storageDB状态绑定
  • 调用storage.storeData只更新了本地持久化存储,没有同步更新StorageContext里的全局状态

修复步骤

1. 调整toggleFavorite逻辑,做不可变更新并同步全局状态

首先要用到你封装的全局setStorageDB方法,修改时生成全新的storageDB对象,不要直接修改原对象:

const useStorage = (name, id, pratice, navigation) => {
  // 先从context取出状态更新方法
  const { storageDB, setStorageDB } = useContext(StorageContext);

  const toggleFavorite = () => {
    // 生成全新的storageDB副本做修改,避免突变原状态
    const newStorageDB = [...storageDB];
    const currentTopicIndex = topicIndex();
    // 生成当前分类的练习数组副本
    const newExercises = [...newStorageDB[currentTopicIndex].exercises];
    const exerciseIndex = newExercises.findIndex(ex => ex.id === id);
    // 生成目标练习的副本并修改favorite属性
    const targetExercise = {
      ...newExercises[exerciseIndex],
      favorite: !newExercises[exerciseIndex].favorite
    };
    newExercises[exerciseIndex] = targetExercise;
    newStorageDB[currentTopicIndex].exercises = newExercises;

    // 同步更新全局context状态,触发所有依赖的组件重渲染
    setStorageDB(newStorageDB);
    // 再更新本地持久化存储
    storage.storeData(newStorageDB);
  };

  // 其他逻辑...
}

2. 调整useStorage的收藏列表计算逻辑,和storageDB绑定

把原来的useEffect触发getFavorites改成用useMemo自动计算,只要storageDB变了就自动更新收藏列表:

const useStorage = (name, id, pratice, navigation) => {
  const { storageDB, setStorageDB } = useContext(StorageContext);

  // 移除原来的favorites状态和对应的getFavorites useEffect逻辑
  const favorites = useMemo(() => {
    const checkFavorites = storageDB.map((store) =>
      store.exercises.filter((exArray) => exArray.favorite)
    );
    const favoritesResult = checkFavorites.filter((ex) => ex.length !== 0);
    return favoritesResult.length ? favoritesResult : null;
  }, [storageDB]); // storageDB变化时自动重新计算

  const toggleFavorite = () => { /* 上面的逻辑 */ }

  return {
    storageDB,
    toggleFavorite,
    favorites
  };
};
export default useStorage;

3. 确认StorageContext的状态更新逻辑正常

要保证setStorageDB是标准的React状态更新方法,是你在定义StorageContext时通过useState声明的:

// 示例StorageContext Provider的逻辑
const StorageProvider = ({ children }) => {
  const [storageDB, setStorageDB = useState(/* 初始值,从AsyncStorage取或者默认值 */);
  // 其他初始化逻辑
  return (
    <StorageContext.Provider value={{ storageDB, setStorageDB }}>
      {children}
    </StorageContext.Provider>
  )
}

修改完成后点击收藏按钮会触发全局storageDB的引用变更,useStorage里的收藏列表会自动更新,FavoritesScreen就会跟着重渲染。


内容的提问来源于stack exchange,提问作者Marshall

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 20:15:02