如何解决axios封装函数调用useDispatch触发Invalid hook call错误
核心原因
React Hook有严格的调用规则,仅支持在React函数组件、自定义Hook的顶层作用域调用,你当前封装的getAxiosQuery是普通工具函数,内部直接调用useDispatch不符合规则,会触发语法报错。
可行方案
方案1:封装为自定义Hook(最符合React规范)
将请求封装改为以use开头的自定义Hook,即可合法调用useDispatch,不需要额外传参:
import { useDispatch } from "react-redux"; import axios from "axios"; import { getPersistedToken } from "src"; // 注意补全processStatusAction的导入 import { PROCESS_STATUS, processStatusAction } from "src/model"; // 自定义Hook,以use开头符合Hook命名规则 export const useAxiosQuery = (endpoint) => { // 顶层调用useDispatch,符合调用规则 const dispatch = useDispatch(); // 返回请求触发函数 const triggerRequest = async () => { try { const res = await axios.get(endpoint, { headers: { 'Authorization': 'Bearer ' + getPersistedToken(), } }); dispatch(processStatusAction(PROCESS_STATUS.DONE)); return res; } catch (error) { dispatch(processStatusAction(PROCESS_STATUS.FAIL)); // 可选:抛出错误方便调用侧做自定义错误处理 throw error; } }; return triggerRequest; };
组件内调用示例:
// 任意函数组件内使用 const DemoComponent = () => { // 调用自定义Hook获取请求触发函数 const getUserInfo = useAxiosQuery('/api/user/info'); const handleQuery = async () => { const res = await getUserInfo(); // 自定义业务逻辑处理返回结果 }; return <button onClick={handleQuery}>获取用户数据</button>; };
Post请求可以按同样逻辑封装为useAxiosPost,支持传入请求体参数即可。
方案2:直接引入Redux Store单例调用dispatch
如果不需要使用Hook,也可以直接导入你项目中初始化完成的Redux Store单例,直接调用store.dispatch,不受Hook规则限制,普通JS场景也能使用:
// 从你项目创建Store的文件导入已初始化的Store实例 import store from 'src/store'; import axios from "axios"; import { getPersistedToken } from "src"; import { PROCESS_STATUS, processStatusAction } from "src/model"; export const getAxiosQuery = (endpoint) => async () => { try { const res = await axios.get(endpoint, { headers: { 'Authorization': 'Bearer ' + getPersistedToken(), } }); // 直接调用store.dispatch,不需要传参也不需要Hook store.dispatch(processStatusAction(PROCESS_STATUS.DONE)); return res; } catch (error) { store.dispatch(processStatusAction(PROCESS_STATUS.FAIL)); throw error; } };
注意:该方案需要确保导出的Store是全局唯一的单例,避免出现循环导入的问题。
内容的提问来源于stack exchange,提问作者Asma_Kh
相关产品推荐
相关产品推荐

