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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:25:15