【问题标题】:How can I use static methods to pass auth tokens to an API class如何使用静态方法将身份验证令牌传递给 API 类
【发布时间】:2019-08-20 17:06:29
【问题描述】:

我编写了一个 API class 与 redux saga 一起使用,以将实际的网络调用与 sagas 分开,该类看起来有点像这样:

    export default class ApiService {

        constructor(bearer) {
            this.instance = axios.create({
                ...
                headers: {
                    'Authorization': `Bearer ${bearer}`
                }
            })
        }

        fetchPosts = async () => {
            const response = this.instance.get(.....)
        }
        ........
    }

但是在我的 sagas 中,我每次都必须在这样的 saga 中实例化一个新对象:

    const { accessToken } = yield select(getAuth)
    const apiService = new ApiService(accessToken);

有没有更好的方法可以让我从每个 saga 调用中删除这 2 行代码,并且仍然确保对象将具有正确的不记名令牌?

谢谢?

【问题讨论】:

    标签: javascript reactjs ecmascript-6 redux redux-saga


    【解决方案1】:

    尝试创建一个函数,该函数仅在第一次调用或更新令牌时返回新的 api 服务。

    api.js

    let api;
    let token;
    
    const isNewToken = (newToken) => newToken !== token;
    const getApi = (newToken) => {
      const isTokenUpdated = newToken !== token;
      const shouldCreateService = !api || isTokenUpdated;
    
      if (shouldCreateService) {
        api = new ApiService(newToken);
      }
    
      return api;
    }
    
    export { getApi }; 
    

    然后创建一些辅助生成器

    function* retrieveToken() {
      return yield select(getAuth);
    }
    
    function* resolveApi() {
      const token = yield retrieveToken();
      return getApi(token); // getApi from api.js
    }
    

    然后在你的主要 sagas 中你可以像这样使用它:

    function* fetchPostsSaga() {
      const api = yield resolveApi();
      // Rest of code using api
      ...
    }
    

    由于授权令牌存储在 Redux 状态 中,ApiService 的创建绑定到 Redux 生命周期。 如果可能的话,我会将 token 的检索移到 Redux 之外。

    【讨论】:

    • 我没有提到静态类的原因是更新静态类中的值是一种代码味道,我会不惜一切代价避免这种情况。
    • 这太棒了!正是我想要的。谢谢你。您能否快速解释一下您对绑定到 Redux 生命周期的 apiService 的含义?我知道我无法在没有 redux 的情况下初始化新的 apiService,但是我该如何避免这种情况呢?
    • 请注意,这只是我的个人意见(可能存在缺陷)。我相信即使在 Redux 之外也应该可以进行 API 调用。这可以通过将令牌创建和存储移到 redux 操作和 saga 之外来实现。如果需要,令牌总是可以被推入 redux 状态(通过动作和减速器)
    【解决方案2】:

    用类变量替换你的承载:

    export default class ApiService {
    
      constructor(bearer) {
    
        this.instance = axios.create({
          ...
          headers: {
            'Authorization': `Bearer ${ApiService.bearer}`
          }
        })
      }
    
      fetchPosts = async () => {
        const response = this.instance.get(.....)
      }
      ........
    }
    

    在你使用它之前,只需在某个地方初始化一次:

    ApiService.bearer = "my bearer";
    

    【讨论】:

      猜你喜欢
      • 2021-04-13
      • 2016-10-01
      • 2015-02-24
      • 2019-06-12
      • 1970-01-01
      • 2019-06-16
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      相关资源
      最近更新 更多