Firebase Auth+Redux登录后页面跳转失败问题求助
问题分析与解决方案
核心问题1:Redux状态字段拼写错误
你的auth reducer里定义的用户字段是currenUser(缺少字母t),但在action和路由组件里都用的是currentUser,导致组件永远无法获取到正确的用户状态,这是路由不跳转的根本原因。
核心问题2:路由组件中未正确导入常量且action字段不匹配
在Route组件的useEffect的else分支中,使用了USER_STATE_CHANGE常量但未导入,同时action里的currentUser字段和reducer里的currenUser不匹配,且未设置loaded: true,导致加载状态无法更新。
核心问题3:登录/注册成功后未主动触发状态更新
虽然依赖Firebase的onAuthStateChanged监听,但部分场景下可能触发不及时,建议在登录/注册成功后手动dispatch获取用户信息的action。
具体修复步骤
1. 修正Reducer中的拼写错误
修改src/redux/reducers/auth.js,统一字段名为currentUser:
import { USER_STATE_CHANGE } from "../constants"; const initialState = { currentUser: null, // 修正拼写 loaded: false, }; export const auth = (state = initialState, action) => { switch (action.type) { case USER_STATE_CHANGE: return { ...state, currentUser: action.currentUser, // 对应action里的字段 loaded: action.loaded, }; default: return state; } };
2. 修正Route组件中的常量导入与action字段
修改src/navigation/main/index.js:
// 导入USER_STATE_CHANGE常量 import { USER_STATE_CHANGE } from "../../redux/constants"; // ...其他代码 useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (user) => { console.log("Executing dispatch"); if (user) { dispatch(getCurrentUserInfo()); } else { dispatch({ type: USER_STATE_CHANGE, currentUser: null, loaded: true, // 加上loaded状态,避免一直显示加载页面 }); } }); return unsubscribe; }, [dispatch]); // 添加dispatch作为依赖,符合React Hook规范
3. 完善登录/注册action,主动触发状态更新
修改src/redux/actions/index.js中的login和register方法,在成功后dispatch获取用户信息:
export const login = (email, password) => (dispatch) => new Promise((resolve, reject) => { signInWithEmailAndPassword(auth, email, password) .then(() => { dispatch(getCurrentUserInfo()); // 登录成功后主动获取用户信息 resolve(); }) .catch((error) => { reject(error); }); }); export const register = (email, password) => (dispatch) => new Promise((resolve, reject) => { createUserWithEmailAndPassword(auth, email, password) .then(() => { dispatch(getCurrentUserInfo()); // 注册成功后主动获取用户信息 resolve(); }) .catch((error) => { reject(error); }); });
4. 验证路由组件的状态判断
现在Route组件中currentUserObj.currentUser可以正确获取到Redux中的用户状态,路由会根据用户是否存在自动切换:
// ...其他代码 return ( <NavigationContainer> <Stack.Navigator> {currentUserObj.currentUser ? ( <Stack.Screen name="home" component={HomeScreen} options={{ headerShown: false }}/> ) : ( <Stack.Screen name="auth" component={AuthScreen} options={{ headerShown: false }} /> )} </Stack.Navigator> </NavigationContainer> );
额外优化建议
- 可以将
onAuthStateChanged的监听逻辑移到Redux的action中(你已经写了userAuthStateListener),在Route组件的useEffect中dispatch这个action,让状态管理更集中:// 在Route组件中替换原有的useEffect useEffect(() => { dispatch(userAuthStateListener()); }, [dispatch]); - 加载页面可以替换为ActivityIndicator,提升用户体验。
内容的提问来源于stack exchange,提问作者Carlos Eduardo Diaz Torres
相关产品推荐
相关产品推荐

