登录API调用后user返回undefined问题咨询及原因排查
问题:调用登录API后无法正确返回user变量
我已成功调用登录API获取数据,返回的data变量包含用户id、token、email等信息,且能在控制台正常打印。但在Redux Thunk的login函数中调用authService.login后,控制台打印user = undefined,表明data变量未正确返回。
相关代码
authService中的login函数
async function login(email: string, password: string, rememberMe: boolean) { const requestOptions = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password, rememberMe }), }; await fetch(`${API_URL}/auth/login`, requestOptions).then((response) => { if (response.ok === true) { response.json().then((data) => { console.log(data); if (data.success === true) { localStorage.setItem("USER_ID", data.id); localStorage.setItem("EMAIL", data.email); localStorage.setItem("ACCESS_TOKEN_KEY", data.token); return data; } else { return Promise.reject(new Error("toast.user.general_error")); } }); } else { return Promise.reject(new Error(response.statusText)); } }); }
Redux Thunk中的login函数
function login(email: string, password: string, rememberMe: boolean) { return (dispatch: ThunkDispatch<{}, void, AnyAction>) => { authService.login(email, password, rememberMe).then( (user) => { history.push("/student/dashboard"); console.log("user = ", user); }, (error) => { dispatch(failure(error.toString())); } ); }; }
原因分析与解决方案
问题根源
你这个authService.login函数虽然加了async关键字,但内部没正确传递返回值:
- 用了
await fetch(...),但没有把整个fetch链式调用的结果返回出去,导致async函数默认返回一个resolved为undefined的Promise; - 嵌套的
response.json().then(...)回调里返回的data,只在内部回调有效,没有传递到外层的.then,更没成为整个async函数的返回值。
修复方案
核心是让authService.login最终返回一个resolved为data的Promise,两种写法任选:
方案1:用async/await替代嵌套.then(推荐,代码更清晰)
把嵌套的.then换成await,逻辑更直观:
async function login(email: string, password: string, rememberMe: boolean) { const requestOptions = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password, rememberMe }), }; const response = await fetch(`${API_URL}/auth/login`, requestOptions); // 先判断请求是否成功 if (!response.ok) { throw new Error(response.statusText); } // 解析返回的JSON数据 const data = await response.json(); console.log(data); if (data.success === true) { localStorage.setItem("USER_ID", data.id); localStorage.setItem("EMAIL", data.email); localStorage.setItem("ACCESS_TOKEN_KEY", data.token); // 返回数据,让外部能拿到 return data; } else { throw new Error("toast.user.general_error"); } }
方案2:保持链式调用,确保每层都返回Promise
如果一定要用.then链式写法,需要把内部的Promise逐层返回出去:
async function login(email: string, password: string, rememberMe: boolean) { const requestOptions = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password, rememberMe }), }; // 必须返回整个fetch的链式调用结果 return fetch(`${API_URL}/auth/login`, requestOptions).then((response) => { if (response.ok === true) { // 这里要返回response.json()的链式调用结果 return response.json().then((data) => { console.log(data); if (data.success === true) { localStorage.setItem("USER_ID", data.id); localStorage.setItem("EMAIL", data.email); localStorage.setItem("ACCESS_TOKEN_KEY", data.token); return data; } else { return Promise.reject(new Error("toast.user.general_error")); } }); } else { return Promise.reject(new Error(response.statusText)); } }); }
修改后,Redux Thunk里的.then就能正确拿到user数据,不会再是undefined了。
内容的提问来源于stack exchange,提问作者wuiiz93
相关产品推荐
相关产品推荐

