如何在Redux Toolkit的React组件外订阅状态 监听signedInUser变更
问题解答
1. 能不能在extraReducers中订阅signedInUser的变更?
首先明确:extraReducers本质是监听Action触发事件,不是监听状态本身的变化。你要监听的signedInUser变更都是由setUserAfterSignIn和signOut这两个Action触发的,所以不管是当前slice还是其他slice的extraReducers都可以监听这两个Action,间接实现监听状态变更的效果。
不过如果是当前slice要处理这两个Action的后续逻辑,不需要用到extraReducers,直接在对应的reducers函数里加逻辑就可以,更简洁。
2. 登录时给axios加授权头的实现方案
不建议每次登录都新增axios拦截器,容易重复添加导致逻辑混乱,有两种更稳妥的实现方式:
- 方式一:直接在登录/登出的reducer里修改axios全局配置
reducers: { signOut: (state) => { state.signedInUser = null // 登出时清除授权头 delete axios.defaults.headers.common['Authorization'] }, setUserAfterSignIn: (state, action: PayloadAction<SignInResult>) => { // 原有逻辑... state.signedInUser = {...} // 登录时设置授权头 axios.defaults.headers.common['Authorization'] = `Bearer ${action.payload.data.accessToken}` } }
- 方式二(更推荐):写全局axios请求拦截器,每次发请求自动拿最新的token
// 单独的axios配置文件 import axios from 'axios' import store from './你的store导出路径' axios.interceptors.request.use((config) => { const signedInUser = store.getState().authentication.signedInUser if (signedInUser?.accessToken) { config.headers.Authorization = `Bearer ${signedInUser.accessToken}` } return config })
这种方式不需要在登录登出时做额外处理,自动适配最新的登录状态,不会出现拦截器重复添加的问题。
3. 其他slice能不能依赖signedInUser的状态?
可以,有两种常用实现方式:
- 方式一:在其他slice的
extraReducers里监听登录/登出的Action,同步更新自己的状态
示例:
import { createSlice } from '@reduxjs/toolkit' import { authenticationSlice } from './authenticationSlice' const otherSlice = createSlice({ name: 'other', initialState: { userRelatedData: null }, extraReducers: (builder) => { builder .addCase(authenticationSlice.actions.setUserAfterSignIn, (state, action) => { // 登录后更新当前slice依赖用户的状态 state.userRelatedData = action.payload.data.xxx }) .addCase(authenticationSlice.actions.signOut, (state) => { // 登出后清空相关状态 state.userRelatedData = null }) } })
- 方式二:如果是组件使用的衍生数据,不需要存储在其他slice里,直接在
useSelector中同时取认证状态和对应slice的状态计算即可,避免状态多份存储导致的数据不一致。
内容的提问来源于stack exchange,提问作者Two Horses
相关产品推荐
相关产品推荐

