登录时存储getUser返回值到localStorage出现[object Promise]问题求助
问题分析与解决方案
问题代码
login(loginId, password) { return axios .post(API_URL + "login", { loginId, password }) .then(response => { console.log(response.data); if (response.data) { localStorage.setItem("token", JSON.stringify(response.data)); localStorage.setItem("user", this.getUser(loginId)); console.log(localstorage.getItem("user")); } console.log(response.data); return response.data; }); } getUser(loginId){ return axios .get(API_URL+"user/search/"+loginId,{ headers: { Authorization: `Bearer ${authHeader()} ` }, }); getCurrentUser() { return (JSON.parse(localStorage.getItem('user'))); } } class ViewMytweetComponent extends Component { constructor(props) { super(props) this.onChangeReply = this.onChangeReply.bind(this); this.state = { Tweet: [], reply: "", user: AuthService.getCurrentUser() } this.deleteTweet = this.deleteTweet.bind(this); } componentDidMount() { const { user } = this.state; console.log(user); var userId = user.loginId; TweetDataService.getMyTweet(userId).then((res) => { this.setState({ Tweet: res.data }); // console.log(this.state.Tweet); }); } }
问题原因
getUser方法返回的是axios请求的Promise对象,你直接把这个Promise存到localStorage里,localStorage会把对象转成字符串"[object Promise]",后续getCurrentUser解析出来的要么是无效JSON,要么就是这个字符串,自然无法获取到正确的loginId,控制台打印[object Promise]就是因为存的是Promise对象本身。
解决步骤
- 等待getUser请求完成:在login的回调逻辑里,必须等待getUser的Promise完成,拿到实际的用户数据后再存到localStorage。
- 存储JSON字符串:localStorage只能存储字符串,所以要把用户数据转成JSON字符串再存入。
- 提取axios返回的实际数据:axios请求返回的response对象中,真实用户数据在
response.data里,需要单独提取。
修正后的代码
方式1:链式调用.then处理异步
login(loginId, password) { return axios .post(API_URL + "login", { loginId, password }) .then(response => { console.log(response.data); if (response.data) { localStorage.setItem("token", JSON.stringify(response.data)); // 先发起getUser请求,将结果传递到下一个then return this.getUser(loginId); } return null; }) .then(userResponse => { if (userResponse?.data) { // 将用户数据转成JSON字符串存入localStorage localStorage.setItem("user", JSON.stringify(userResponse.data)); console.log(localStorage.getItem("user")); } return userResponse?.data; }); } getUser(loginId){ return axios.get(API_URL+"user/search/"+loginId,{ headers: { Authorization: `Bearer ${authHeader()} ` }, }); } getCurrentUser() { const userStr = localStorage.getItem('user'); // 处理localStorage无数据的情况,避免JSON.parse报错 return userStr ? JSON.parse(userStr) : null; }
方式2:用async/await简化异步逻辑
async login(loginId, password) { try { const loginResponse = await axios.post(API_URL + "login", { loginId, password }); console.log(loginResponse.data); if (loginResponse.data) { localStorage.setItem("token", JSON.stringify(loginResponse.data)); // 等待getUser请求完成,拿到用户数据 const userResponse = await this.getUser(loginId); if (userResponse.data) { localStorage.setItem("user", JSON.stringify(userResponse.data)); console.log(localStorage.getItem("user")); } } return loginResponse.data; } catch (error) { console.error(error); throw error; } } getUser(loginId){ return axios.get(API_URL+"user/search/"+loginId,{ headers: { Authorization: `Bearer ${authHeader()} ` }, }); } getCurrentUser() { const userStr = localStorage.getItem('user'); return userStr ? JSON.parse(userStr) : null; }
组件部分调整
因为登录是异步操作,建议在组件挂载时确认用户数据是否存在,避免初始化时拿不到数据:
class ViewMytweetComponent extends Component { constructor(props) { super(props) this.onChangeReply = this.onChangeReply.bind(this); this.deleteTweet = this.deleteTweet.bind(this); this.state = { Tweet: [], reply: "", user: null } } componentDidMount() { const user = AuthService.getCurrentUser(); if (user) { this.setState({ user }, () => { TweetDataService.getMyTweet(user.loginId).then((res) => { this.setState({ Tweet: res.data }); }); }); } else { // 处理未登录场景,比如跳转登录页 console.log("用户未登录"); } } }
内容的提问来源于stack exchange,提问作者Sravani Upputuri
相关产品推荐
相关产品推荐

