使用Redux Toolkit createAsyncThunk存储用户状态及本地存储异常问题
问题分析与解决方案
1. 变量顺序错误导致Thunk未正确绑定
在userSlice.js中,createAsyncThunk定义的setUserAsync位于createSlice之后,JavaScript变量提升特性会导致createSlice执行时setUserAsync还是undefined,进而使extraReducers无法正确绑定Thunk的状态回调,甚至可能导致Thunk无法正常执行。
修复:
将setUserAsync的定义移到createSlice之前:
import {createSlice , createAsyncThunk} from '@reduxjs/toolkit' import {userService} from '../services/user-service' const initialState = { user: null, loading: false, error: null } // 先定义Thunk export const setUserAsync = createAsyncThunk( 'user/userservice', async (loggedInUser) => { console.log(loggedInUser); const user = await userService.login(loggedInUser) // 这里user是userService返回的用户对象,不是带data属性的响应,直接返回user return user } ) // 再创建Slice const userSlice = createSlice({ name: 'user', initialState, reducers: { setUser(state, action) { state.user = action.payload }, }, extraReducers: (builder) => { builder.addCase(setUserAsync.pending, (state) => { state.loading = true state.error = null // 原代码中state.user为null时修改state.user.status会报错,改为操作全局loading状态 }) .addCase(setUserAsync.fulfilled, (state, action) => { state.loading = false state.user = action.payload }) .addCase(setUserAsync.rejected, (state, action) => { state.loading = false state.error = action.error.message }) } }) export const { setUser } = userSlice.actions export const selectUser = (state) => state.user.user export default userSlice.reducer
2. StorageService的store函数无返回值
storageService.js中的store函数仅设置localStorage,但未返回存储的值,导致userService.login中newUser为undefined,最终Thunk返回undefined,无法正确更新Redux状态。
修复:
让store函数返回存储的用户对象:
function store(key, value) { localStorage[key] = JSON.stringify(value); return value; // 返回存储的值,或者返回load(key)确保格式一致 } function load(key, defaultValue = null) { var value = localStorage[key] || defaultValue; return JSON.parse(value); } export const storageService = { store, load }
3. UserService中返回值的冗余Promise包装
userService.js中的login函数本身是async函数,无需手动调用Promise.resolve,直接返回值即可:
修复:
import { storageService } from "./storage-service"; export const userService = { login } const USER_KEY = 'user' export async function login(user) { console.log(user); const newUser = storageService.store(USER_KEY, user) console.log(newUser); return newUser; // async函数自动包装为Promise }
4. 组件中Dispatch的正确性检查
确保组件中正确导入并调用setUserAsync:
import { useDispatch } from 'react-redux'; import { setUserAsync } from './path/to/userSlice'; // 在组件内部 const dispatch = useDispatch(); // 登录逻辑中调用 const handleLogin = (userInfo) => { dispatch(setUserAsync(userInfo)); };
完成以上修复后,Thunk中的console.log应该能正常输出,用户信息会同时存入Redux状态和localStorage。
内容的提问来源于stack exchange,提问作者Amit Amar
相关产品推荐
相关产品推荐

