Redux+JWT项目编辑用户资料时local storage JWT token更新异常求解
核心问题定位
editProfileaction中解构api.signUp返回值错误:后端接口返回的响应数据默认挂载在data字段下,你写的const { data2 } = await api.signUp(formData)会导致data2为undefined,后续传给AUTHaction的 payload 为空,自然localStorage里存的就是空对象。
- 你dispatch的
DELETEaction没有对应的reducer处理逻辑,不会触发localStorage清除操作,你之前定义的EDIT类型的action才会清本地存储,这里类型不匹配。
- 你dispatch的
- 异步操作时序问题:你没有等dispatch操作完成就执行
history.push,可能出现页面跳转后状态还未更新的问题。
- 异步操作时序问题:你没有等dispatch操作完成就执行
修复代码
修改editProfile action即可
export const editProfile = (formData, history) => async (dispatch) => { try { // 删除旧账户 await api.editProfile(formData) // 创建新账户,正确解构返回的data字段 const { data } = await api.signUp(formData) // 先触发已定义的EDIT action,清空旧的本地存储 dispatch({ type: EDIT }) // 触发AUTH action存入新的token和用户信息 dispatch({ type: AUTH, data }) // 所有状态更新完成后再跳转页面 history.push("/profile"); } catch (error) { console.log("error here", error); } };
reducer逻辑无需修改,上述修改完成后即可正常更新localStorage中的token和用户信息。
更优实现方案(推荐替换删除重建逻辑)
删除重建的逻辑会导致用户ID变更,后续关联用户的业务数据(比如用户发布的内容、收藏等)都会失效,建议直接用PATCH接口更新用户信息:
- 后端新增用户信息更新接口,校验JWT后直接修改对应用户的字段,返回更新后的用户信息和新的JWT(如果JWT payload中没有需要更新的字段也可以复用旧token)
- 前端新增对应API调用,action写法参考如下:
export const editProfile = (formData, history) => async (dispatch, getState) => { try { // 从当前redux状态中获取旧token传给后端做鉴权 const token = getState().auth.authData.token const { data } = await api.editProfile(formData, token) // 直接用新的用户信息更新本地存储和redux状态,无需删除重建账户 dispatch({ type: AUTH, data }) history.push("/profile") } catch (error) { console.log(error) } }
这种方案更符合接口设计规范,也不会产生不必要的数据库删除/写入操作,不会破坏用户关联数据。
内容的提问来源于stack exchange,提问作者Gordon Maloney
相关产品推荐
相关产品推荐

