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

RTK createAsyncThunk更新状态后useSelector返回初始值问题

问题描述

我尝试通过HTTP GET请求配合createAsyncThunk实现随机用户的会话鉴权,在App.js的组件挂载钩子中拉取用户数据。我可以在浏览器网络面板中看到对应的GET请求,也能在Redux DevTools中查看到拉取后的最新状态,但TopBar.js中useSelector返回的始终是拉取前的初始状态。

TopBar.js 控制台用户日志截图:
TopBar控制台日志截图


相关代码

App.js 代码

const dispatch = useDispatch();

useEffect(() => {
  dispatch(fetchRandomUserData())
}, [dispatch]);

authSlice.js 代码

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';

const initialState = {
  isLoggedIn: true,
  user: {},
  loading: false,
  error: null,
};

export const fetchRandomUserData = createAsyncThunk(
  'auth/fetchRandomUser',
  async () => {
    try {
      const response = await fetch('https://randomuser.me/api/');
      const data = await response.json();
      return data.results[0];
    } catch (error) {
      throw Error(error);
    }
  }
);

const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    logout(state, action) {
      state.isLoggedIn = false;
    },
  },
  extraReducers: {
    [fetchRandomUserData.pending]: (state, action) => {
      state.loading = true;
      state.error = null;
    },
    [fetchRandomUserData.fulfilled]: (state, action) => {
      console.log("action.payload",action.payload);
      state.user = action.payload;
      state.loading = false;
    },
    [fetchRandomUserData.rejected]: (state, action) => {
      state.error = action.error.message;
      state.loading = false;
    },
  },
});

export const { logout } = authSlice.actions;

export default authSlice.reducer;

store.js 代码

import { configureStore } from '@reduxjs/toolkit';
// import booksReducer from './reducers/booksReducer';
import booksReducer from './slices/bookSlice';
import authReducer from './slices/authSlice';

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

export default store;

TopBar.js 代码

export default function TopBar(): JSX.Element {
  const user = useSelector((state: any) => state.auth);
  console.log("topbar",user); // 始终返回初始状态

  //....
}

问题原因&解决方案

这个问题和thunk、slice的业务写法无关,DevTools能看到状态更新说明数据流逻辑完全正常,问题出在Store连接层,按优先级排查:

  • 首先检查项目入口文件(通常是main.jsx/index.jsx)的<Provider>配置:必须全局只存在一个Provider包裹整个应用,且传入的store是你store.js中导出的、注册了authReducer的唯一实例,不要在其他文件重复调用configureStore创建新store。
  • 确认TopBar组件在Provider的子树范围内:如果TopBar写在了<Provider store={store}>标签的外层,它会读取不到你更新的store状态。
    入口文件正确写法参考:
    import React from 'react'
    import ReactDOM from 'react-dom/client'
    import App from './App'
    import store from './store'
    import { Provider } from 'react-redux'
    
    ReactDOM.createRoot(document.getElementById('root')!).render(
      <Provider store={store}>
        <App />
        {/* 所有用到useSelector/useDispatch的组件,必须放在这对Provider标签内部 */}
      </Provider>
    )
    
  • 最后检查useSelector的引入来源,必须是从react-redux包引入,不要引错自定义同名方法或其他包的同名API。

你当前useSelector((state) => state.auth)的写法本身没有问题,Redux对selector返回的对象做浅比较,状态更新后会正常触发组件重渲染,不需要修改这部分逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:18:21