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

在React Native中结合React Navigation使用useContext遇错求助

修复Context错误并实现trackList持久化

一、解决TypeError: Cannot read property '_context' of undefined错误

问题根源

App.js中Stack.Navigator外层被多余的大括号包裹,导致React无法正确解析组件结构,破坏了Context的作用域传递逻辑。

修复步骤

修改App.js的返回部分,移除Stack.Navigator外层的冗余大括号:

// 修改后的App.js完整代码
import { createStackNavigator } from "@react-navigation/stack";
import Home from "./Screens/Home";
import Host from "./Screens/Host";
import Join from "./Screens/Join";
import { NavigationContainer } from "@react-navigation/native";
import React, { useState, createContext } from "react";
const Stack = createStackNavigator();

export const HostContext = createContext(null)
export default function App() {
  const [trackList, setTrackList] = useState([]);

  return (
    <HostContext.Provider value={{trackList, setTrackList}}>
      <NavigationContainer>
        <Stack.Navigator
          initialRouteName="Home"
          screenOptions={{ gestureEnabled: false }}
        >
          <Stack.Screen name="Home" component={Home} />
          <Stack.Screen name="Host" component={Host} />
          <Stack.Screen name="Join" component={Join} />
        </Stack.Navigator>
      </NavigationContainer>
    </HostContext.Provider>
  );
}

二、修复Host.js的闭包陷阱问题

Host.js中useEffect的依赖数组为空,导致回调内捕获的trackList始终是初始空数组,更新时会丢失历史数据。改用函数式更新规避闭包问题:

// 修改后的Host.js useEffect部分
useEffect(() => {
  setTrackListener(roomID, (t) => {
    if (t != null) {
      console.log(t.name);
      // 通过函数式更新获取最新状态,避免闭包陷阱
      setTrackList(prevList => [...prevList, t.name]);
    }
  })
}, [roomID]); // 添加roomID到依赖数组,确保监听逻辑仅在roomID变化时重新执行

三、实现trackList持久化(关闭页面不重置)

使用@react-native-async-storage/async-storage将数据保存到本地存储,确保页面重启后数据不丢失:

1. 安装依赖

npm install @react-native-async-storage/async-storage
# 或使用yarn
yarn add @react-native-async-storage/async-storage

2. 升级App.js,添加持久化逻辑

import { createStackNavigator } from "@react-navigation/stack";
import Home from "./Screens/Home";
import Host from "./Screens/Host";
import Join from "./Screens/Join";
import { NavigationContainer } from "@react-navigation/native";
import React, { useState, createContext, useEffect } from "react";
import AsyncStorage from '@react-native-async-storage/async-storage'; // 导入AsyncStorage

const Stack = createStackNavigator();

export const HostContext = createContext(null)

export default function App() {
  const [trackList, setTrackList] = useState([]);

  // 组件挂载时加载本地存储的trackList
  useEffect(() => {
    const loadSavedTracks = async () => {
      const savedData = await AsyncStorage.getItem('trackList');
      if (savedData) {
        setTrackList(JSON.parse(savedData));
      }
    };
    loadSavedTracks();
  }, []);

  // trackList更新时自动保存到本地存储
  useEffect(() => {
    const saveTracks = async () => {
      await AsyncStorage.setItem('trackList', JSON.stringify(trackList));
    };
    saveTracks();
  }, [trackList]);

  return (
    <HostContext.Provider value={{trackList, setTrackList}}>
      <NavigationContainer>
        <Stack.Navigator
          initialRouteName="Home"
          screenOptions={{ gestureEnabled: false }}
        >
          <Stack.Screen name="Home" component={Home} />
          <Stack.Screen name="Host" component={Host} />
          <Stack.Screen name="Join" component={Join} />
        </Stack.Navigator>
      </NavigationContainer>
    </HostContext.Provider>
  );
}

完成以上修改后,既可以解决Context传递错误,又能保证关闭页面重新打开后trackList的数据不会丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:27:11