在 ReactJS + Redux 中同时从 LocalStorage 写入然后读取

Write and then read at the same time from LocalStorage in ReactJS + Redux

我正在尝试写入 localStorage,然后从 localStorage 身份验证令牌中读取以访问 API。

export const authLogin = (username, password) => {
  return (dispatch) => {
    dispatch(authStart());
    axios
      .post(" http://localhost:8000/rest-auth/login/", {
        username: username,
        password: password,
      })
      .then((res) => {
        const token = res.data.key;
        const expirationDate = new Date(new Date().getTime() + 3600 * 1000);
        try {
          localStorage.setItem("token", token);
          localStorage.setItem("expirationDate", expirationDate);
          dispatch(authSuccess(token));
          dispatch(checkAuthTimeout(3600));
        } catch (error) {
          console.log("error storing data");
        }
      })
      .catch((err) => {
        dispatch(authFail(err));
      });
  };
};

然后从我想从 localStorage 中读取的 ReactJS 方法:

import axios from "axios";
import { endpoint } from "./constants";
var token = localStorage.getItem("token");

export const authAxios = axios.create({
  baseURL: endpoint,
  headers: {
    Authorization: `Token ${token ? localStorage.getItem("token") : null}`,
  },
});

class OrderSummary extends React.Component {
  _isMounted = false;
  state = {
    data: null,
    error: null,
    loading: false,
  };
  componentDidMount() {
    this._isMounted = true;
    this.handelFetchOrder();
  }

  componentWillUnmount() {
    this._isMounted = false;
  }
  handelFetchOrder = () => {
    this.setState({ loading: true });
    authAxios
      .get(orderSummaryURL)
      .then((res) => {
        this.setState({ data: res.data, loading: false });
        console.log(res.data);
      })
      .catch((err) => {
        if (err.response.status === 404) {
          this.setState({
            error: "You currently do not have any order",
            loading: false,
          });
        } else {
          this.setState({ error: err, loading: false });
        }
      });
  };

我的问题是当我从 localStorage 读取 时。如果令牌变为空。这会导致 401 api 代码,因为我们无法读取令牌以将其传递给 api 以获得结果。但是,如果我刷新网络浏览器 (F5),则一切正常。

在您的示例中,您在加载文件时为 axios 设置令牌。这意味着只有在应用程序加载时,而不是在您登录后。因此 localStorage 中的项目当时为空。

所以解决方案是为 axios 设置拦截器而不是 authAxios:

const App = (props) => {

  // This will trigger when only once when page refreshes
  useEffect(() => {
    axios.interceptors.request.use(
      (config) => {
        config.headers = {
          ...config.headers,
          Authorization: `Token ${token ? localStorage.getItem("token") : null}`
        };

        return config;
      },
      (error) => {
        props.dispatchRedirectToLoginPage()
        return Promise.reject(error);
      }
    );
  }, [])

  return <div>Your app</div>
}

这样每个请求都会执行这个函数,并且会从localStorage中获取token。

您使用 axios.get(...) 或您需要的任何方法进行的每个 api 调用。