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

Redux Toolkit useSelector返回undefined问题求助

Redux状态更新后组件无法获取最新值的问题

问题描述

登录时dispatch了login、setToken、setUserInfo这几个reducer函数,控制台显示Redux状态已按预期更新,但在Homepage组件中用useSelector获取状态时,得到的是undefined或false,无法显示用户名。


相关代码

配置Redux Store(store.js)

import { configureStore } from "@reduxjs/toolkit";
import authReducer from "./auth";

const store = configureStore({
    reducer: {
        auth: authReducer,
    },
});

export default store;

创建Auth Slice(auth.js)

import {createSlice} from "@reduxjs/toolkit";

const initialAuthState = {
    loggedIn: false,
    userToken: "",
    userData: []
};

const authSlice = createSlice({
    name: "auth",
    initialState: initialAuthState,

    reducers: {
        login(state) {
            state.loggedIn = true;
        },
        setToken(state, action) {
            state.userToken = action.payload;
        },
        setUserInfo(state, action) {
            state.userData = action.payload;
        },
        logout(state) {
            state.loggedIn = initialAuthState.loggedIn;
            state.userToken = initialAuthState.userToken;
            state.userData = initialAuthState.userData;
        },
    },
});

export const authActions = authSlice.actions;
export default authSlice.reducer;

使用状态的Homepage组件(Homepage.jsx)

import {Container} from "../helpers/Container";
import {Title} from "../helpers/Title";
import {useSelector} from "react-redux";
import {useEffect, useState} from "react";

import store from "../../store/store";

function Homepage() {
    const [userData, setUserData] = useState([])
    let loggedin = useSelector((state) => state?.auth?.loggedIn);
    let user = useSelector((state) => state?.auth?.userData);
    let userTk = useSelector((state) => state?.auth?.userToken);

    useEffect(() => {
        console.log("user: ", user)  // undefined
        console.log("userTk: ", userTk) // undefined
        console.log("loggedin: ", loggedin) // false
        setUserData(user)
    }, [])
    return (
        <Container>
            <div>-{user}-{userTk}-{loggedin}</div>
            <Title titleText={"Welcome"} user={userData?.userName}/>
        </Container>
    );
}

export default Homepage;

问题原因及解决办法

1. useEffect依赖项缺失

你的useEffect使用了空依赖数组[],只会在组件首次挂载时执行一次。此时登录流程可能还没完成,Redux状态尚未更新;后续状态变化时,useEffect也不会重新执行,导致本地userData一直是初始值。

2. 多余的本地state

不需要将Redux状态同步到组件本地useState中,直接使用useSelector获取的值即可,避免数据不同步。

3. 初始值类型不匹配

initialAuthState中userData设为数组[],但实际登录后传入的是用户对象(需要取userName属性),类型不匹配会导致userData?.userName取不到值。


修改方案

方案1:简化Homepage组件

移除本地state和无用的useEffect,直接使用Redux状态:

import {Container} from "../helpers/Container";
import {Title} from "../helpers/Title";
import {useSelector} from "react-redux";

function Homepage() {
    const loggedin = useSelector((state) => state.auth.loggedIn);
    const user = useSelector((state) => state.auth.userData);
    const userTk = useSelector((state) => state.auth.userToken);

    return (
        <Container>
            <div>-{user?.userName}-{userTk}-{loggedin.toString()}</div>
            <Title titleText={"Welcome"} user={user?.userName}/>
        </Container>
    );
}

export default Homepage;

方案2:修正Auth Slice的初始状态

将userData初始值改为空对象,匹配实际数据类型:

const initialAuthState = {
    loggedIn: false,
    userToken: "",
    userData: {} // 改为空对象
};

方案3:确保登录时dispatch顺序正确

登录成功后按顺序dispatch,确保状态更新完整:

// 示例登录逻辑
import { authActions } from '../store/auth';

const handleLogin = async () => {
    // 调用登录接口获取用户信息和token
    const { userInfo, token } = await loginApi();
    
    // 依次dispatch更新状态
    dispatch(authActions.setUserInfo(userInfo));
    dispatch(authActions.setToken(token));
    dispatch(authActions.login());
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:03:20