Redux Saga 调用不使用 localStorage 令牌

Redux Saga call not taking localStorage tokens

我最近开始学习 Redux Saga 和 Redux Toolkit,遇到了 redux-saga 和 toolkit 的问题。

我正在尝试创建一个登录系统,将令牌放置在您的系统中,然后每当应用程序首次加载时,它都会从数据库中获取用户详细信息,如果它 return 是 401,那么用户未登录,我将 return 设置为未定义。这使我能够隐藏不应该可见的组件。这是最好的方向吗,你有什么建议吗?

看来axios抓取到localStorage的数据没有被handler使用? 它是异步执行下一个任务吗? 我必须在那里使用 actionChannel 吗?如果是这样我将如何实现它,它指出 'pattern' 但它变得非常混乱,因为他们不使用带有 createSlices 的 redux-toolkit 并且仅使用 redux?

从登录数据通过 formData 提交,watcher saga 看到我已经命中 logInUser 并将其发送到正确的处理程序。 handler 然后获取数据,使用 yield call(requestLogInUser) 通过 axios 将其发送,并将操作作为有效负载。然后将来自 axios 的响应放在 res 中,从中提取两个令牌并设置在本地存储中(有效)。

之后yield call(handleGetCurrentUser);应该启动 getCurrentUser 处理程序并使用在 localStorage 中设置的令牌实际从数据库中获取用户详细信息数据。

然而发生的事情是数据没有被调用,它只是给我 401,这意味着它没有 find/try 从 localStorage 获取令牌,即使 axios 要求它。这让我觉得这是因为它是异步的,并且在设置令牌之前以某种方式触发 yield 调用?我根本找不到它使用 redux 开发工具尝试该操作,但我注意到它因为 console.log 而将其触发,并且它 return 在那个 api 端点上设置了 401。

我在 Login.js 中的提交按钮显示 formData 的调度

  const handleSubmit = (e) => {
    e.preventDefault();
    dispatch(logInUser(formData));
  };

我的 User.js 文件包含所有 处理程序:

export function* handleLogInUser(action) {
  try {
    const res = yield call(requestLogInUser, action.payload);
    yield localStorage.setItem("access_token", res.data.access_token);
    yield localStorage.setItem("refresh_token", res.data.refresh_token);
    yield call(handleGetCurrentUser);
  } catch (error) {
    console.log(error);
  }
}

export function* handleGetCurrentUser() {
  try {
    console.log("in request get user");
    const response = yield call(requestGetCurrentUser);
    const { data } = response;
    yield put(setCurrentUser({ ...data }));
  } catch (error) {
    console.log(error);
  }
}

export function* handleSetCurrentUser(data) {
  try {
    console.log("in request set user");
    yield put(setCurrentUser({ data }));
  } catch (error) {}
}

我的 user.js 请求 文件,其中包含 Axios 请求

export function requestLogInUser(formData) {
  return axiosLogInInstance.post(`auth/token/`, {
    grant_type: "password",
    username: formData.email,
    password: formData.password,
    client_id: "asdfasdfasdfdfsdfassfsfWJFdQ",
  });
}

export function requestGetCurrentUser() {
  return axiosInstance.get("/user/currentUser/");
}

我的axiosInstance

const baseURL = "http://127.0.0.1:8000/api/";

const axiosInstance = axios.create({
  baseURL: baseURL,
  timeout: 5000,
  headers: {
    Authorization: "Bearer " + localStorage.getItem("access_token"),
    "Content-Type": "application/json",
    accept: "application/json",
  },
});

我的 UserSlice.js 包含切片的文件

const userSlice = createSlice({
  name: "user",
  initialState: {},
  reducers: {
    logInUser(state, action) {},
    getCurrentUser() {},
    setCurrentUser(state, action) {
      const userData = action.payload;
      return { ...state, ...userData };
    },
  },
});

最后 Rootsaga 文件

export function* watcherSaga() {
  //authentication/user
  yield takeLeading(logInUser.type, handleLogInUser);
  yield takeLatest(getCurrentUser.type, handleGetCurrentUser);
}

你关于sagas和react的代码是对的,问题是axiosInstance,在代码中,axios只得到localstorage一个创建实例时,添加axios请求拦截器

axiosInstance.interceptors.request(config => {
  config.headers.Authorization = "Bearer " + localStorage.getItem("access_token")
  return config
}, null)