React配合Firebase Auth登录后跳转读取userInfo.email报错问题
问题根因
你的login是异步action,调用dispatch(login(email, password))后,代码不会等待firebase登录、redux状态更新完成就直接执行了history.push('/shoplist')跳转到列表页。此时USER_LOGIN_SUCCESS还未触发,redux中userInfo还未赋值,所以读取userInfo.email会抛出空值错误。刷新页面后store初始化会直接从localStorage读取已经缓存的userInfo,因此能正常访问。
修复方案
- 确认你的异步action返回Promise(使用redux-thunk中间件的话按如下结构调整login方法即可)
// userAction.js 调整login方法结构 export const login = (email, password) => async (dispatch) => { try { dispatch({ type: USER_LOGIN_REQUEST }) const logUser = await firebaseAuth.signInWithEmailAndPassword(email, password) console.log(logUser.user) dispatch({ type: USER_LOGIN_SUCCESS, payload: logUser.user, }) localStorage.setItem('userInfo', JSON.stringify(logUser.user)) } catch (error) { dispatch({ type: USER_LOGIN_FAIL, payload: error.message }) } }
- 修改login.js的提交逻辑,等待异步action执行完成后再跳转
// login.js 修改submitHandler为异步函数 const submitHandler = async (e) => { e.preventDefault() await dispatch(login(email, password)) history.push('/shoplist') }
- 增加防御性代码避免空值报错,在shoplist.js中使用可选链访问属性,或者加loading判断:
// shoplist.js 调整写法 const userLogin = useSelector((state) => state.userLogin) const { loading, userInfo } = userLogin // 加载中可以先渲染加载状态 if (loading) return <div>加载中...</div> // 可选链访问避免空值报错 console.log(userInfo?.email)
内容的提问来源于stack exchange,提问作者4est
相关产品推荐
相关产品推荐

