Redux Store派发Action后未更新问题求助
React + Redux Toolkit 登录后Token无法存入Store问题
我是React新手,最近一周在用React和Redux Toolkit对接Django REST Framework做登录功能。我理解Redux的Action Creator创建Action后派发给Reducer修改全局状态,但我的登录Action Creator无法将access和refresh token存入Store!以下是我的代码:
Login.js - 登录逻辑核心及Action调用处
import { useState } from "react" import {useDispatch, useSelector} from "react-redux" import {login} from '../features/auth/authSlice' import axios from "axios" const Login = () => { const userToken = useSelector((state)=>state.auth) const [username, setUsername] = useState('') const [password, setPassword] = useState('') const dispatch = useDispatch() const authenticate = async ()=>{ // const resp = await axios.post('http://localhost:8000/auth/login', {formData}) const resp = await fetch('http://localhost:8000/auth/login', { method: 'POST', headers:{ 'Content-Type': 'application/json' }, body:JSON.stringify({username:username, password:password}) }) const data = await resp.json() console.log(data); dispatch(login({ accessToken: data.access, refreshToken: data.refresh })) return data } const handleSubmit = (e) =>{ e.preventDefault() console.log(username, password); // authenticate().then((data)=>{ }) authenticate() setTimeout(()=>{ console.log(userToken); }, 3000) console.log(userToken); } return ( <div> <h1>Login</h1> <div className="Auth-form-container"> <form className='Auth-form' onSubmit={handleSubmit}> <div className="Auth-form-content"> <h2 className='Auth-form-title'>Login SSl Test</h2> <div className="form-group mt-3"> <label>Username</label> <input type="text" className="form-control mt-1" placeholder="Enter username" value={username} onChange={(e)=>setUsername(e.target.value)} /> </div> <div className="form-group mt-3"> <label>Password</label> <input type="password" className="form-control mt-1" placeholder="Enter password" value={password} onChange={(e)=>setPassword(e.target.value)} /> </div> <div className="d-grid gap-2 mt-3"> <button type="submit" className="btn btn-primary"> Submit </button> </div> </div> </form> </div> </div> ); } export default Login;
AuthSlice.js - 认证相关Redux Toolkit Slice
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; const initialState = { accessToken: null, refreshToken: null } const authSlice = createSlice({ name:'auth', initialState, reducers:{ login:(state, action)=>{ state.accessToken = action.payload.accessToken state.refreshToken = action.payload.refreshToken }, logout:(state, action)=>{ state.accessToken = '' state.refreshToken = '' } } }); export const {login, logout} = authSlice.actions export default authSlice.reducer
问题排查与解决
- 闭包导致的状态捕获问题
你在handleSubmit里直接打印的userToken,以及setTimeout里的userToken,都是组件执行handleSubmit时捕获的旧状态闭包值,Redux状态更新后组件会重新渲染,但旧的闭包值不会自动更新。正确做法是用useEffect监听状态变化:
import { useState, useEffect } from "react" const Login = () => { const userToken = useSelector((state)=>state.auth) // 监听auth状态变化,自动打印最新值 useEffect(() => { console.log('最新Auth状态:', userToken); }, [userToken]) // 其余代码不变 }
- 确认Store配置正确性
检查你的Store配置文件(通常为store.js),确保正确注册了authSlice的reducer,且key为auth(与useSelector中的state.auth对应):
import { configureStore } from '@reduxjs/toolkit'; import authReducer from '../features/auth/authSlice'; export const store = configureStore({ reducer: { auth: authReducer, // 必须保证此key为auth }, });
验证API返回数据结构
确认fetch返回的data中确实包含access和refresh字段,可通过控制台打印的data值核对。如果后端返回字段名不符(比如access_token),需调整dispatch(login)中的赋值逻辑。异步逻辑顺序不影响状态更新
authenticate是异步函数,但dispatch本身是同步操作,只要API返回正确,状态会被立即更新,无需等待异步函数完成。组件会在状态更新后自动重新渲染,此时useSelector会拿到最新值。
内容的提问来源于stack exchange,提问作者jamesc
相关产品推荐
相关产品推荐

