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

React Native中组件已用Provider包裹仍遇Redux上下文缺失错误

React Native Redux Toolkit 会话管理报错解决

问题描述

我是React Native新手,尝试用Redux Toolkit实现会话管理,代码遵循官方文档编写,且已用<Provider>包裹组件,但仍报错:

could not find react redux context value please ensure the component is wrapped in

尝试了网上各种方法都无法解决,相关代码如下:

AppNavigation.tsx

import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';

import Signup from '../Screens/Signup';
import NewSignIn from '../Screens/NewSignIn';
import FullfillmentScreen from '../../FullfillmentScreen';
import Combined from '../Screens/Combined';
import Oragnization from '../Screens/Oragnization';
import {useDispatch, useSelector} from 'react-redux/es/exports';
import {onAuthStateChanged} from 'firebase/auth';
import {auth} from '../../firebase/firebase.config';
import {setUser} from '../redux/slices/user';
const Stack = createNativeStackNavigator();

const AppNavigation = () => {
const {user} = useSelector(state => state.user);

const dispatch = useDispatch();

onAuthStateChanged(auth, u => {
console.log('GOT USER====>', u);
dispatch(setUser(u)); //setting user in redux store
});
if (user) {
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{headerShown: false}}>
{/* <Stack.Screen name="NewSignIn" component={NewSignIn} /> */}
<Stack.Screen name="Organization" component={Oragnization} />
<Stack.Screen name="Combined" component={Combined} />
<Stack.Screen
name="FullfillmentScreen"
component={FullfillmentScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
} else {
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name="NewSignIn" component={NewSignIn} />
<Stack.Screen name="Signup" component={Signup} />
{/* <Stack.Screen name="Organization" component={Oragnization} />
<Stack.Screen name="Combined" component={Combined} />
<Stack.Screen
name="FullfillmentScreen"
component={FullfillmentScreen}
/> */}
</Stack.Navigator>
</NavigationContainer>
);
}
};

export default AppNavigation;

App.tsx

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 */

import React, {useState, useEffect} from 'react';
import type {PropsWithChildren} from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  useColorScheme,
  View,
} from 'react-native';

import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Signin from './src/Screens/Signin';
import MaigicLink from './src/Screens/MaigicLink';
import Oragnization from './src/Screens/Oragnization';
//import Splash from './src/Screens/Splash';
import SplashScreen from 'react-native-splash-screen';
import {auth} from './firebase/firebase.config';
import NewSignIn from './src/Screens/NewSignIn';
import Signup from './src/Screens/Signup';

import FullfillmentScreen from './FullfillmentScreen';
import Combined from './src/Screens/Combined';
import {Provider} from 'react-redux';
import {store} from './src/redux/store';
import {useSelector} from 'react-redux/es/exports';
import AppNavigation from './src/navigation/AppNavigation';

//const Stack = createNativeStackNavigator();

const App = () => {
  useEffect(() => {
    SplashScreen.hide();
  }, []);

  return (
    <Provider store={store}>
      <AppNavigation />
    </Provider>

   
  );
};

export default App;

Store.tsx

import {configureStore} from '@reduxjs/toolkit';
import user from './slices/user';

export const store = configureStore({
  reducer: {
    user,
  },
});

user.tsx(Slice)

import {createSlice} from '@reduxjs/toolkit';
import type {PayloadAction} from '@reduxjs/toolkit';

// Define a type for the slice state
interface userState {
  user: string;
}

// Define the initial state using that type
const initialState: userState = {
  user: '',
};

export const userSlice = createSlice({
  name: 'counter',
  // `createSlice` will infer the state type from the `initialState` argument
  initialState,
  reducers: {
    setUser: (state, action) => {
      state.user = action.payload;
    },
  },
});

export const {setUser} = userSlice.actions;

export default userSlice.reducer;

问题原因及解决方法

1. 错误的Redux Hooks导入路径

你从react-redux/es/exports导入useDispatch和useSelector,这属于内部私有路径,会导致Redux上下文识别异常。必须从官方导出路径导入:

// 替换原导入语句
import {useDispatch, useSelector} from 'react-redux';

2. 未在useEffect中注册Auth监听器

直接在组件函数体内调用onAuthStateChanged会导致每次组件渲染都注册新的监听器,不仅浪费资源,还可能在组件未完全挂载到Redux上下文时触发dispatch,引发上下文错误。将逻辑放到useEffect中:

const AppNavigation = () => {
  const {user} = useSelector(state => state.user);
  const dispatch = useDispatch();

  useEffect(() => {
    // 注册监听器并保存取消订阅函数
    const unsubscribe = onAuthStateChanged(auth, u => {
      console.log('GOT USER====>', u);
      dispatch(setUser(u));
    });

    // 组件卸载时取消监听,避免内存泄漏
    return unsubscribe;
  }, [dispatch]);

  // ...后续代码
};

3. 重复渲染NavigationContainer

在if/else分支中分别渲染NavigationContainer会创建多个导航实例,干扰Redux上下文传递。将NavigationContainer提到条件判断外部:

const AppNavigation = () => {
  // ...useSelector和useEffect逻辑

  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{headerShown: false}}>
        {user ? (
          <>
            <Stack.Screen name="Organization" component={Oragnization} />
            <Stack.Screen name="Combined" component={Combined} />
            <Stack.Screen name="FullfillmentScreen" component={FullfillmentScreen} />
          </>
        ) : (
          <>
            <Stack.Screen name="NewSignIn" component={NewSignIn} />
            <Stack.Screen name="Signup" component={Signup} />
          </>
        )}
      </Stack.Navigator>
    </NavigationContainer>
  );
};

4. Slice类型定义错误

你的user slice将user定义为string类型,但Firebase返回的是User对象或null,类型不匹配会导致状态异常。修正类型定义:

import {createSlice} from '@reduxjs/toolkit';
import type {PayloadAction} from '@reduxjs/toolkit';
import type {User} from 'firebase/auth'; // 导入Firebase User类型

interface UserState {
  user: User | null;
}

const initialState: UserState = {
  user: null,
};

export const userSlice = createSlice({
  name: 'user', // 修正slice名称,语义化
  initialState,
  reducers: {
    setUser: (state, action: PayloadAction<User | null>) => {
      state.user = action.payload;
    },
  },
});

export const {setUser} = userSlice.actions;
export default userSlice.reducer;

总结

按照以上四点修改后,Redux上下文的问题应该能解决,同时代码的规范性和稳定性也会提升。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:14:56