Redux-Saga中带Access Token的Axios GET请求失效排查
React项目JWT请求报错:无法读取null的authService属性
问题场景
使用Axios、Redux和Redux-Saga的React项目,请求Laravel后端JWT保护的接口时抛出TypeError: 无法读取null的authService属性。本地存储已正确保存登录Token,但请求时无法正确传递。直接在组件用useState发起请求可正常工作,怀疑问题出在Saga调度逻辑中。
相关代码
页面组件
import { useEffect } from "react"; import { getAllPostsAction } from "../../store/posts/slice"; import { useSelector, useDispatch } from "react-redux"; import { makeSelectPosts } from "../../store/posts/selector"; export const PostsPage = () => { const posts = useSelector(makeSelectPosts); const dispatch = useDispatch(); useEffect(() => { dispatch(getAllPostsAction()); }, [dispatch]); console.log(posts); return <h1>PostsPage</h1>; };
Saga代码
import { call, put, all, fork, takeEvery } from "redux-saga/effects"; import { postService } from "../../services/PostService"; import { setAllPostsAction } from "./slice"; import { setSinglePostAction } from "./slice"; function* getPosts() { try { const response = yield call(postService.getAll); yield put(setAllPostsAction(response.data)); } catch (err) { console.error(err); } } function* getPostsSagaWatcher() { yield takeEvery("posts/getAllPostsAction", getPosts); } // 下方文件中已fork所有watcher
PostService代码
import { authService } from "./AuthService"; import axios from "axios"; class PostService { constructor() { this.authService = authService; } async getAll() { return await axios.get("http://127.0.0.1:8000/api/posts", { headers: this.authService.getHeaders(), }); } // 其他方法 }
AuthService的getHeaders方法
getHeaders() { return { Authorization: `Bearer ${window.localStorage.getItem("loginToken")}`, }; }
问题原因与解决方案
核心原因
TypeError的本质是PostService实例的this指向异常,导致this.authService为null。在Saga中调用postService.getAll时,如果postService未正确实例化,或者调用方式导致this丢失绑定,就会触发该错误。
解决步骤
确保PostService正确导出实例
修改PostService的导出代码,创建类的实例并导出,而非导出类本身:// PostService.js末尾添加 export const postService = new PostService();若之前导出的是类(
export default PostService),会导致postService是类构造函数而非实例,调用getAll时this指向错误。检查AuthService的导出方式
确认AuthService同样是实例导出,而非类:// AuthService.js示例 class AuthService { getHeaders() { return { Authorization: `Bearer ${window.localStorage.getItem("loginToken")}`, }; } } export const authService = new AuthService();若
authService未实例化,PostService构造函数中this.authService会是null。可选:改用函数式服务简化逻辑
若不需要类的特性,可将服务改为纯函数,避免this绑定问题:// PostService.js import axios from "axios"; export const postService = { getAll: async () => { const token = window.localStorage.getItem("loginToken"); return await axios.get("http://127.0.0.1:8000/api/posts", { headers: { Authorization: `Bearer ${token}` }, }); }, };这种方式无需处理类实例和this指向,逻辑更简洁。
内容的提问来源于stack exchange,提问作者qouillyan
相关产品推荐
相关产品推荐

