React项目Axios字符串插值失效与登录后请求异常问题求助
问题描述
- 在
fetchRequestByEmployee方法中,使用字符串插值传递employeeId时请求失效,硬编码ID则正常,且已确认能从context正确获取ID值。 - 用户登出后
token和user设为null,但应用会重复处理axios请求,必须刷新页面才能恢复正常,希望避免登录后需刷新的操作。
相关代码
1. app.js 获取员工信息代码
useEffect(() => { const fetchEmployeeInfo = async() => { try { let response = await axios.get(`http://127.0.0.1:8000/api/employees/user/${user.id}/`, { headers: { Authorization: "Bearer " + token, }, }); setEmployeeData(response.data); setEmployeeInfo(response.data); setEmployeeId(response.data.id); } catch (error) { console.log(error.message); } }; fetchEmployeeInfo(); }, [user, employee, token]);
2. 首页获取ptoRequest信息代码
useEffect(() => { const fetchPtoRequestByEmployee = async(employeeId) => { console.log(employeeId) try { let response = await axios.get(`http://127.0.0.1:8000/api/pto_requests/employee/${employeeId}/`, { headers: { Authorization: "Bearer " + token, }, }); console.log(employeeId) console.log(response.data) setPtoRequests(response.data); } catch (error) { console.log(error.response); } }; fetchPtoRequestByEmployee(); }, [token, employeeId, ]);
3. 用户登出代码
const logoutUser = () => { if (user) { localStorage.removeItem("token"); setUser(null); setToken(null); navigate("/"); } };
解决方案
1. 修复字符串插值失效问题
问题出在调用fetchPtoRequestByEmployee时未传入employeeId参数,导致函数内的employeeId为undefined,插值后URL无效。修改调用逻辑:
useEffect(() => { const fetchPtoRequestByEmployee = async(employeeId) => { // 先判断参数是否有效,避免无效请求 if (!employeeId || !token) return; console.log(employeeId) try { let response = await axios.get(`http://127.0.0.1:8000/api/pto_requests/employee/${employeeId}/`, { headers: { Authorization: "Bearer " + token, }, }); console.log(response.data) setPtoRequests(response.data); } catch (error) { console.log(error.response); } }; // 传入employeeId参数 fetchPtoRequestByEmployee(employeeId); }, [token, employeeId]);
2. 解决登出后重复请求及需刷新问题
- 添加请求前置校验:在发起请求前判断
token和employeeId是否存在,避免无效请求 - 优化app.js的useEffect依赖:原依赖中的
employee可能导致不必要的重渲染,若employee未在该effect内使用,可移除;同时添加状态校验,避免user.id为null时发起请求 - 清空登出状态:登出时同步清空员工相关状态,防止触发无效请求
修改app.js的effect:
useEffect(() => { // 校验user和token是否有效 if (!user?.id || !token) return; const fetchEmployeeInfo = async() => { try { let response = await axios.get(`http://127.0.0.1:8000/api/employees/user/${user.id}/`, { headers: { Authorization: "Bearer " + token, }, }); setEmployeeData(response.data); setEmployeeInfo(response.data); setEmployeeId(response.data.id); } catch (error) { console.log(error.message); } }; fetchEmployeeInfo(); }, [user, token]); // 移除不必要的employee依赖
修改登出逻辑:
const logoutUser = () => { if (user) { localStorage.removeItem("token"); setUser(null); setToken(null); setEmployeeId(null); // 清空employeeId,避免触发无效请求 setEmployeeData(null); setEmployeeInfo(null); navigate("/"); } };
额外优化:添加请求取消逻辑
在首页的effect中添加CancelToken,防止组件卸载或状态变化时的竞态请求:
useEffect(() => { const source = axios.CancelToken.source(); const fetchPtoRequestByEmployee = async(employeeId) => { if (!employeeId || !token) return; try { let response = await axios.get(`http://127.0.0.1:8000/api/pto_requests/employee/${employeeId}/`, { headers: { Authorization: "Bearer " + token, }, cancelToken: source.token }); setPtoRequests(response.data); } catch (error) { if (axios.isCancel(error)) return; // 忽略取消的请求 console.log(error.response); } }; fetchPtoRequestByEmployee(employeeId); // 组件卸载或依赖变化时取消请求 return () => source.cancel('请求已取消'); }, [token, employeeId]);
内容的提问来源于stack exchange,提问作者MidwestDIY
相关产品推荐
相关产品推荐

