React项目中Redux Action Payload为Null的问题排查求助
问题:Redux Action payload 为 Null(Firebase 认证场景)
我使用原生Redux开发React项目,结合Firebase进行身份认证,尝试通过dispatch setCurrentUser Action传入用户信息,但最终触发的Action payload始终为null:
{type: 'SET_CURRENT_USER', payload: null}
相关代码如下:
Action Creator
export const setCurrentUser = user => ({ type: 'SET_CURRENT_USER', payload: user, });
User Reducer
const INITIAL_STATE = { currentUser: null, }; const userReducer = (state = INITIAL_STATE, action) => { switch (action.type) { case 'SET_CURRENT_USER': return { ...state, currentUser: action.payload, }; default: return state; } };
App组件
class App extends React.Component { unsubscribeFromAuth = null; unsubscribeFromSnapshot = null; componentDidMount() { const { setCurrentUser } = this.props; this.unsubscribeFromAuth = auth.onAuthStateChanged(async userAuth => { if (userAuth) { const userRef = await createUserProfileDocument(userAuth); this.unsubscribeFromSnapshot = onSnapshot(userRef, snapShot => { setCurrentUser({ id: snapShot.id, ...snapShot.data(), }); }); } else { setCurrentUser(null); } }); } componentWillUnmount() { if (this.unsubscribeFromAuth) this.unsubscribeFromAuth(); if (this.unsubscribeFromSnapshot) this.unsubscribeFromSnapshot(); } render() { return ( <div> <Header /> <Routes> <Route path="/" element={<HomePage />} /> <Route path="/shop" element={<ShopPage />} /> <Route path="/signin" element={<SignInAndSignUpPage />} /> </Routes> </div> ); } } const mapDispatchToProps = dispatch => ({ setCurrentUser: user => dispatch(setCurrentUser(user)), });
解决方案
1. 排查createUserProfileDocument函数的返回值
createUserProfileDocument是获取Firestore用户文档引用的核心函数,如果它未返回有效引用,后续onSnapshot监听会失效,导致无法触发带用户数据的dispatch。
给该函数添加调试日志,确认执行流程:
async function createUserProfileDocument(userAuth) { if (!userAuth) return null; const userRef = firestore.doc(`users/${userAuth.uid}`); const snapShot = await userRef.get(); console.log('用户文档快照:', snapShot); console.log('用户文档是否存在:', snapShot.exists); if (!snapShot.exists) { const { displayName, email } = userAuth; const createdAt = new Date(); try { await userRef.set({ displayName, email, createdAt }); console.log('用户文档创建成功'); } catch (error) { console.error('创建用户文档失败:', error); } } return userRef; }
2. 检查onSnapshot监听逻辑
确认onSnapshot是否正确触发,以及快照数据是否有效。添加错误回调和数据日志:
this.unsubscribeFromSnapshot = onSnapshot(userRef, snapShot => { console.log('快照ID:', snapShot.id); console.log('快照数据:', snapShot.data()); setCurrentUser({ id: snapShot.id, ...snapShot.data(), }); }, error => { console.error('快照监听失败:', error); });
如果snapShot.data()返回null,说明Firestore文档中未存储用户数据,需检查文档创建逻辑是否正确。
3. 确认Firebase认证状态触发时序
onAuthStateChanged会在组件挂载时立即触发一次,若用户未登录会先执行setCurrentUser(null);后续用户登录时才会触发用户数据的dispatch。添加日志确认每次触发的userAuth值:
this.unsubscribeFromAuth = auth.onAuthStateChanged(async userAuth => { console.log('认证状态变化:', userAuth); if (userAuth) { // 原有逻辑 } else { console.log('用户未登录'); setCurrentUser(null); } });
4. 验证Redux连接配置
确保App组件已通过connect正确绑定Redux的dispatch方法,否则setCurrentUser不会被注入到props中:
// 务必添加这行代码,导出连接后的组件 export default connect(null, mapDispatchToProps)(App);
内容的提问来源于stack exchange,提问作者Abdelkader Boukhalfoun
相关产品推荐
相关产品推荐

