React Native Expo应用报错:未找到react-redux上下文值,需用<Provider>包裹
问题修复:React Redux Provider包裹顺序错误导致的Context缺失
错误原因
你在App组件内部直接调用了useSelector,但<Provider store={store}>是在App组件的return语句中才渲染的——这意味着App组件本身并没有被Provider包裹,所以useSelector无法获取到Redux的Context,从而抛出报错。
修复方案
将使用Redux Hooks的逻辑拆分为内部子组件,让Provider完整包裹所有需要访问Redux状态的组件:
修复后的完整App.js代码
import * as React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { createDrawerNavigator } from '@react-navigation/drawer'; import { Provider, useSelector } from 'react-redux'; import store from './store/store'; import { Ionicons } from '@expo/vector-icons'; // 导入你的屏幕组件 import HomeScreen from './screens/HomeScreen'; import SettingsScreen from './screens/SettingsScreen'; import ProfileScreen from './screens/ProfileScreen'; import FaqScreen from './screens/FaqScreen'; import LoginScreen from './screens/LoginScreen'; import LogoutScreen from './screens/LogoutScreen'; const Tab = createBottomTabNavigator(); const Drawer = createDrawerNavigator(); const HomeIcon = ({ size, color }) => <Ionicons name="home-outline" size={size} color={color} />; const ProfileIcon = ({ size, color }) => <Ionicons name="person-outline" size={size} color={color} />; const SettingsIcon = ({ size, color }) => <Ionicons name="settings-outline" size={size} color={color} />; const LoginIcon = ({ size, color }) => <Ionicons name="log-in-outline" size={size} color={color} />; function MyTabs({ isLoggedIn }) { return ( <Tab.Navigator screenOptions={{headerShown: false}} initialRouteName="Home"> <Tab.Screen name="Home" component={HomeScreen} options={{ tabBarIcon: ({ color, size }) => <HomeIcon size={size} color={color} />, }} /> <Tab.Screen name="Settings" component={SettingsScreen} options={{ tabBarIcon: ({ color, size }) => <SettingsIcon size={size} color={color} />, }} /> {isLoggedIn ? ( <Tab.Screen name="Profile" component={ProfileScreen} options={{ tabBarIcon: ({ color, size }) => <ProfileIcon size={size} color={color} />, }} /> ) : ( <Tab.Screen name="Login" component={LoginScreen} options={{ tabBarIcon: ({ color, size }) => <LoginIcon size={size} color={color} />, }} /> )} </Tab.Navigator> ); } // 拆分出内部组件,所有使用Redux Hooks的逻辑放在这里 function AppContent() { const isLoggedIn = useSelector((state) => state.auth.isLoggedIn); return ( <NavigationContainer initialRouteName="Home"> <Drawer.Navigator> <Drawer.Screen name="Shop" component={MyTabs} /> <Drawer.Screen name="FAQ" component={FaqScreen} /> {isLoggedIn ? <Drawer.Screen name="Logout" component={LogoutScreen} /> : null} </Drawer.Navigator> </NavigationContainer> ); } function App() { return ( <Provider store={store}> <AppContent /> </Provider> ); } export default App;
关键改动说明
- 将原来
App组件中调用useSelector和渲染导航的逻辑,移到新的AppContent组件中 - 让
<Provider>直接包裹AppContent,确保所有使用Redux Hooks的组件都在Provider的Context范围内
内容的提问来源于stack exchange,提问作者Priyank
相关产品推荐
相关产品推荐

