向自定义Hook传递函数参数报checkForRefreshTokenUpdate未定义错误
问题根因
你的代码存在明确的逻辑/写法错误,是触发报错的直接原因,同时还有一处隐藏的功能bug:
- 核心报错原因:传参写法错误+可能存在的定义顺序问题
你在MainStore中调用assets时写的是assets(checkForRefreshTokenUpdate()),末尾的()会让JS引擎执行到这行时立刻访问、执行checkForRefreshTokenUpdate函数:- 如果这行调用的位置在
const checkForRefreshTokenUpdate = async () => {...}定义语句之前,会触发const的暂时性死区限制,直接抛出你遇到的ReferenceError: checkForRefreshTokenUpdate is not defined报错。 - 就算定义顺序正确,这种写法也只是把
checkForRefreshTokenUpdate()的执行结果(Promise实例)传入下游,而非函数本身的引用,后续拦截器尝试把入参当做函数调用时,会触发"is not a function"的类型错误。
正确传参需要去掉函数末尾的调用括号,直接传入函数引用,同时保证函数定义在调用语句之前。
- 如果这行调用的位置在
- 隐藏逻辑bug:Promise回调无返回值
在getAssetData方法的.then回调中,你写的是res => { res.data }:箭头函数用大括号包裹代码块时必须手动写return才能返回值,当前写法不会返回接口数据,调用getAssetData拿到的结果永远是undefined。 - 额外注意:你定义的
assets、interceptedAxios没有遵循React自定义Hook的use开头命名规范,如果在React组件体系外调用这些函数,会脱离Hook调用规则校验,后续容易出现闭包陈旧值的问题。
修正后代码
MainStore 部分
export const MainStore = () => { // ... 其余原有逻辑 // 先定义函数,再传入引用 const checkForRefreshTokenUpdate = async () => { // ... 原有token刷新逻辑 } // 去掉函数调用括号,传入函数本身 const { getAssetData } = assets(checkForRefreshTokenUpdate); // ... 其余原有逻辑 }
assets 部分
export const assets = ( checkForRefreshTokenUpdate ) => { const { customAxios } = interceptedAxios(checkForRefreshTokenUpdate); /** * Fetches asset data. * @returns */ const getAssetData = async (params) => { const url = buildUrl({ baseUrl: getBaseUrl(), endpoint: "/api/asset", params }); const reqOpts = { headers: { Accept: "application/json", "Content-Type": "application/json", Authorization: `Bearer ${getAccessToken()}` } }; // 修正then回调的返回值 return customAxios.get(url, reqOpts).then(res => res.data); }; return { getAssetData } }
interceptedAxios 部分
这部分逻辑本身无语法问题,只要上游传入正确的函数引用即可正常运行:
export const interceptedAxios = ( checkForRefreshTokenUpdate ) => { const customAxios = axios.create(); customAxios.interceptors.request.use(async (config) => { if (config.url.includes(getBaseUrl()) && config.headers["Authorization"] != null) { await checkForRefreshTokenUpdate() .then((token) => { if (token != null) { config.headers["Authorization"] = `Bearer ${token}`; } }); } return config; }, (error) => { return Promise.reject(error); }); return { customAxios } }
内容的提问来源于stack exchange,提问作者billysk
相关产品推荐
相关产品推荐

