React TypeScript:如何根据用户类型动态获取正确的Axios请求URL?
问题分析与优化方案
嘿,我瞅了你的代码,发现请求失败的直接原因很明显——你定义的url是个需要传参的函数,但调用axios.get的时候直接把函数本身传进去了,Axios可没法把函数当URL用呀!而且你的URL配置存在大量冗余,每个用户类型都重复定义几乎相同的对象,后续维护会特别麻烦。下面给你一套更简洁靠谱的解决方案:
第一步:重构全局URL配置,消除冗余
我们用模板占位符+动态替换的方式,只维护一套基础URL模板,再根据用户类型动态生成对应URL,彻底告别重复代码:
class DevelopmentGlobals extends Globals{ // 定义基础URL模板,用{role}作为用户类型的占位符 private baseUrlTemplates = { coupons: "http://localhost:8080/{role}/coupons/", images: "http://localhost:8080/api/cats/images/", companies:"http://localhost:8080/{role}/company/", login:"http://localhost:8080/{role}/login", customerPurchase:"http://localhost:8080/customer/" } // 根据用户类型获取对应的URL集合 getUrlsForRole(role: string | null) { // 统一转小写处理,兼容不同大小写的角色值 const targetRole = role?.toLowerCase() || "guest"; // 遍历模板,替换占位符生成最终URL return Object.entries(this.baseUrlTemplates).reduce((urlMap, [key, template]) => { // 特殊处理login接口:访客的login是固定的/guest/login if (key === "login") { urlMap[key] = targetRole === "guest" ? "http://localhost:8080/guest/login" : template.replace("{role}", targetRole); } // customerPurchase不需要替换占位符,直接用模板 else if (key === "customerPurchase") { urlMap[key] = template; } // 其他接口替换{role}占位符 else { urlMap[key] = template.replace("{role}", targetRole); } return urlMap; }, {} as Record<string, string>); } }
第二步:简化组件中的URL获取逻辑
现在组件里不用再写一堆if-else判断,一行代码就能拿到当前用户对应的所有URL,还能避免原代码里的函数调用错误:
function CouponsList(): JSX.Element { const init: CouponModel[] = []; const[coupons, setCoupons] = useState<any>(init); const isLoggedIn = authService.getIsLoggenedIn(); const clientType = authService.getType(); // 直接获取当前用户对应的所有URL const currentUrls = globals.getUrlsForRole(clientType); const headers: any = { authorization : authService.getToken() }; const getCoupons = async()=>{ // 使用currentUrls里的coupons URL,同时传入请求头 const response = await axios.get<any>(currentUrls.coupons, { headers }); setCoupons(response.data); // 别忘了更新优惠券状态哦 } const purchase = async(coupon: CouponModel)=>{ console.log(coupon); try { const res = await axios.put<CouponModel>(currentUrls.customerPurchase, coupon, {headers}); console.log(JSON.stringify(res.data)); // 购买成功后可以刷新优惠券列表 getCoupons(); } catch(err) { console.log(err); } } // 组件挂载时自动获取优惠券列表(可根据业务逻辑调整触发时机) useEffect(() => { getCoupons(); }, [clientType]); // rest code... }
这个方案的优势
- 减少冗余:只维护一套URL模板,不用重复复制粘贴相同的URL字符串
- 降低出错概率:避免手动写if-else判断时的拼写错误或漏判情况
- 扩展性强:后续新增用户类型时,只需要在
getUrlsForRole方法里调整逻辑,不用新增整个URL对象 - 代码更简洁:组件里的URL获取逻辑一目了然,可读性大幅提升
内容的提问来源于stack exchange,提问作者chanak
相关产品推荐
相关产品推荐

