使用相同的操作清除和重置本地存储中用户的 JWT 令牌

Clear and reset user's JWT token in local storage with same action

我正在制作一个组件,用户可以在其中更改他们的详细信息,而我这样做的方式是,他们实际上是在删除他们的帐户并重新制作它 - 使用 Redux 和 JWT 来完成。如果有更好的方法,请告诉我,但目前这对我有用。

当用户首次创建帐户时,它会在本地存储中使用正确的详细信息设置他们的 JWT 令牌。那很好用。他们登录时也没有问题。

问题是,当他们调用“编辑”功能删除他们的帐户并创建一个新帐户时,上述情况并没有发生。因此,如果我创建一个用户名为“aaa”的帐户,应用程序会显示该帐户的配置文件密钥和我创建的值。但是当我调用编辑它时 - 例如用户名“bbb”,即使新帐户 已成功创建(显示在我的 MongoDB 中,可以登录), 不是正确更新令牌 - 键的值显示为 {} 的空对象。

是否有一种简单的方法来清除 然后 更新我丢失的令牌?想要一只手!

我的操作在这里:

import * as api from "../api";
import { AUTH, DELETE } from "./ActionTypes";

export const signin = (formData, history) => async (dispatch) => {
  try {
    const { data } = await api.signIn(formData)

    dispatch({ type: AUTH, data })

    history.push("/");
  } catch (error) {
    console.log(error);
  }
};

export const signup = (formData, history) => async (dispatch) => {
  try {
    const { data } = await api.signUp(formData)
    
    dispatch({ type: AUTH, data })

    history.push("/");
  } catch (error) {
    console.log(error);
  }
};


export const editProfile = (formData, history) => async (dispatch) => {
  try {

    const { data } = await api.editProfile(formData)
    const { data2 } = await api.signUp(formData)

    Promise.resolve(dispatch({ type: DELETE, data })).then(
    () => dispatch({ type: AUTH, data2 }))

    history.push("/profile");

  } catch (error) {
    console.log("error here", error);
  }
};

我的减速器在这里:

import { AUTH, LOGOUT, EDIT, REFRESH } from "../actions/ActionTypes";

const authReducer = (state = { authData: null }, action) => {
  switch (action.type) {
    case AUTH:
      localStorage.setItem('profile', JSON.stringify({...action?.data}));

      return {...state, authData: action.data};
      break;
    case LOGOUT:
    
        localStorage.clear()
        return {...state, authData: null};

      return state;
      break;

    case EDIT:

      localStorage.clear()
      return {...state, authData: null};

    default:
      return state;
      break;
  }
};

export default authReducer;

我的 GitHub 项目在这里:https://github.com/gordonmaloney/lingr-mern/

(顺便说一句,在我放弃并来到 Stack Overflow 提问之前,我花了一整天的时间试图弄清楚如何修补细节,但是当我输入我的问题时,它突然出现了我知道我可以通过删除和重新创建来尝试做到这一点,我现在 非常接近 将它放在我想要的位置最后这个小颠簸真的让我很沮丧!)

你在这里有一点 Promises 眩晕。让我们探索 editProfile 函数,特别是这一点:

Promise.resolve(dispatch({ type: DELETE, data })).then(/* ... */)

我将在 Promise.resolve():

上引用文档

Promise.resolve() method returns a Promise object that is resolved with a given value

dispatch() returns一个Promise本身。因此,您在这里所做的是将 dispatch 返回的承诺包装到另一个承诺中,通过调用 Promise.resolve() 立即解决这个“外部”承诺,然后您正在调度 AUTH动作。

你应该做的是:

dispatch({ type: DELETE, data })).then(() => dispatch({ type: AUTH, data2 }));

或者,我认为哪个读起来更好:

await dispatch({ type: DELETE, data });

await dispatch({ type: AUTH, data2 });

history.push("/profile");

这意味着您将等待 dispatch 完成,然后调用第二次调度。

我解决了!

这是因为两个 reducer 都在寻找 action.data,这是最初调用注册操作的方式。但是因为它在作为编辑操作的一部分被调用时被称为“data2”,所以它找不到任何东西来更新令牌。我更改了名称,现在可以正常使用了。

供参考,新代码如下:

操作:

import * as api from "../api";
import { AUTH, DELETE } from "./ActionTypes";

export const signin = (formData, history) => async (dispatch) => {
  try {
    const { data } = await api.signIn(formData)

    dispatch({ type: AUTH, data })

    history.push("/");
  } catch (error) {
    console.log(error);
  }
};

export const signup = (formData, history) => async (dispatch) => {
  try {
    const { data } = await api.signUp(formData)
    
    dispatch({ type: AUTH, data })

    history.push("/");
  } catch (error) {
    console.log(error);
  }
};


export const editProfile = (formData, history) => async (dispatch) => {
  try {

    const { data2 } = await api.editProfile(formData)
    const { data } = await api.signUp(formData)

    await dispatch({ type: DELETE, data2 });

    await dispatch({ type: AUTH, data });

    history.push("/profile");

  } catch (error) {
    console.log(error);
  }
};

减速器:

import { AUTH, LOGOUT, EDIT, REFRESH } from "../actions/ActionTypes";

const authReducer = (state = { authData: null }, action) => {
  switch (action.type) {
    case AUTH:
      localStorage.setItem('profile', JSON.stringify({...action?.data}));

      console.log(action)

      return {...state, authData: action.data};
      break;

    case LOGOUT:
    
        localStorage.clear()
        return {...state, authData: null};
      break;

    case EDIT:

      localStorage.clear()
      localStorage.setItem('profile', JSON.stringify({...action?.data2}));
      return {...state, authData: null};

    default:
      return state;
      break;
  }
};

export default authReducer;