Redux Toolkit中createAsyncThunk获取传入token值异常问题
问题原因
核心是你对createAsyncThunk的参数规则理解错误:
createAsyncThunk生成的action仅支持传入1个参数作为payload,你调用dispatch(createNewJsonResponse(newJsonResponse, token))时传入的第二个参数token会被直接丢弃,根本不会传入thunk回调。createAsyncThunk的payload回调(也就是你定义的async函数)的第二个参数是Redux Toolkit内置的thunkAPI对象,包含dispatch、getState、rejectWithValue、signal、requestId等内置属性,你控制台打印出来的非预期对象就是这个thunkAPI,根本不是你传入的token。
另外你的代码还存在一个隐藏bug:在ResponseDesign组件顶层直接执行dispatch(setToken(token)),没有做执行时机控制,会触发组件无限重渲染。
解决方案
修复createAsyncThunk的传参与取值逻辑
二选一即可,更推荐第二种方式:
方式1:多参数打包为单个对象传入
createAsyncThunk只支持单参数传值,需要传递多个值时把所有内容打包为一个对象传入即可:
- 修改ChatDesign组件中的dispatch调用:
// 原错误写法 // dispatch(createNewJsonResponse(newJsonResponse, token)); // 修改为 dispatch(createNewJsonResponse({ responseData: newJsonResponse, token }));
- 修改createAsyncThunk的回调逻辑,从第一个参数中解构取值:
export const createNewJsonResponse = createAsyncThunk ( "new-json-response/post", async ({ responseData, token }) => { console.log('当前token:', token); // 此处可拿到正确的字符串类型token // 注意:你原来的接口调用也没传token,记得补上 const res = await FaqsService.createNewResponse(responseData, token); return res.data; } );
方式2:直接在thunk中从Store读取token(推荐)
既然token已经存在Redux Store中,完全不需要层层传递props,直接通过thunkAPI提供的getState方法从Store读取即可,省去组件传参步骤:
- 将ChatDesign组件中的dispatch调用改回仅传入业务参数:
dispatch(createNewJsonResponse(newJsonResponse));
- 修改createAsyncThunk回调,通过thunkAPI获取Store中的token:
export const createNewJsonResponse = createAsyncThunk ( "new-json-response/post", async (responseData, { getState }) => { // 取值的key和你configureStore中注册的userSlice对应的key、useSelector的取值路径保持一致 const token = getState().userToken; console.log('当前token:', token); // 此处可拿到正确的字符串类型token const res = await FaqsService.createNewResponse(responseData, token); return res.data; } );
修复组件无限重渲染bug
将ResponseDesign组件中顶层执行的token初始化存储逻辑移入useEffect,保证仅在组件挂载时执行一次:
import { useSelector, useDispatch } from "react-redux"; import { useState, useEffect } from "react"; // 其余导入保持不变 const ResponseDesign = () => { const dispatch = useDispatch(); // 将顶层的token获取、dispatch逻辑移入useEffect useEffect(() => { const token = getAccessTokenApi(); dispatch(setToken(token)); }, [dispatch]); const sendtoken = useSelector(state=>state.userToken); // 其余组件逻辑保持不变
内容的提问来源于stack exchange,提问作者ddaudiosolutions
相关产品推荐
相关产品推荐

