【问题标题】:Write and then read at the same time from LocalStorage in ReactJS + Redux在 ReactJS + Redux 中同时从 LocalStorage 写入然后读取
【发布时间】:2020-11-17 21:50:33
【问题描述】:

我正在尝试写入 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) 则一切正常。

【问题讨论】:

    标签: javascript reactjs redux persistent-storage


    【解决方案1】:

    在您的示例中,您在文件加载时为您的 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。

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

    【讨论】:

    • 谢谢@Mario Petrovic,我只是想知道您所说的 isAuthTokenCall 是什么意思?
    • 很好,很高兴我能帮上忙
    • 我很抱歉 isAuthTokenCall 这是我的代码中我遗漏的东西
    • 您应该在主组件 App 中的 useEffect 中设置它,可能在您的情况下。我将通过实现来编辑我的答案,如果出现 401 或任何其他错误,您可以使用组件方法进行操作
    • 正如@MarioPetrovic 所说,使用 useEffect 可能会解决问题。在我的情况下是这样
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 2017-10-13
    相关资源
    最近更新 更多