【问题标题】:Mobx forcing computed values to updateMobx 强制计算值更新
【发布时间】:2019-03-24 09:48:06
【问题描述】:

我正在使用 Mobx 来处理我的 React 应用程序中的一些状态。

我的应用使用 JWT 进行身份验证。通过令牌和刷新令牌。

我已经建立了一家商店,并按以下方式工作:

class generalStore {
    isLoggedIn = localStorage.getItem('token') !== null ? true : false;
    name = localStorage.getItem('token') !== null ? jwtdecode(localStorage.getItem('token')).name : null;
    role = localStorage.getItem('token') !== null ? jwtdecode(localStorage.getItem('token')).role : null;

    login(name, role) {
        this.isLoggedIn = true;
        this.name = name;
        this.role = role;
    }

    logout() {
        this.isLoggedIn = false;
        this.name = null;
        this.role = null;
    }
}

decorate(generalStore, {
    isLoggedIn: observable,
    name: observable,
    role: observable,
    login: action,
    logout: action
})

const store = new generalStore()

当在应用程序的其他地方调用登录/注销时,这将按预期工作。

但是,如果 JWT 格式错误(手动通过开发控制台),jwtdecode 函数会抛出错误并且整个应用程序崩溃 - 不理想。我可能是偏执狂,畸形的 JWT 不应该在野外经常发生,但我喜欢健壮。

然后我想我可以使用计算值来缓解这个问题:

class generalStore {
    constructor() {
        try {
            this.decoded = jwtdecode(localStorage.getItem('token'))
        } catch(err) {
            this.decoded = null
        }
    }

    get isLoggedIn() {
        if (this.decoded) {
            return true
        } else {
            return false
        }
    }


    get name() {
        if (this.decoded) {
            return this.decoded.name
        } else {
            return false
        }
    }

    get role() {
        if (this.decoded) {
            return this.decoded.role
        } else {
            return false
        }
    }
}

decorate(generalStore, {
    isLoggedIn: computed,
    name: computed,
    role: computed,
})

但是当本地存储在登录时使用新令牌更新时,计算值不会自动更新,必须刷新应用程序(因此也刷新存储),然后计算值才能反映现在存在的令牌。

有没有办法强制更新计算值?或者我可以处理jwtdecode 在我的商店(第一个代码块)中定义可观察对象时抛出错误吗?

或者不应该关注格式错误的 JWT?如果我负责的话,我似乎应该这样做......

【问题讨论】:

    标签: javascript reactjs jwt mobx


    【解决方案1】:

    我认为这不起作用,因为 this.decoded 不可观察,因此 mobx 无法跟踪对其的更新以强制更新计算属性。

    在所有mobx examples 中,它们都使用基于其他可观察值的计算属性。

    因此,您的选择是使 decoded 可观察,或者使用方法而不是计算属性。

    class generalStore {
    
        decoded = null;
    
        constructor() {
            try {
                this.decoded = jwtdecode(localStorage.getItem('token'))
            } catch(err) {
                this.decoded = null
            }
        }
    
        // ...
    }
    
    decorate(generalStore, {
        decoded: observable,
        // ...
    });
    

    【讨论】:

    • 我不知道如何将 decoded 定义为构造函数内的可观察对象,或在构造函数之外使用 try/catch 块来缓解格式错误的 JWT。
    • @BML91 查看示例here 有一个类Person 具有一些类属性,然后在它们下方标记为可观察
    • 这就是我定义我的类的方式——因为我没有使用装饰器。这些示例都没有说明如何在构造函数之外执行 try/catch observable 或如何使用 try/catch 块定义 observable?
    猜你喜欢
    • 2021-12-19
    • 2020-09-02
    • 2019-06-21
    • 2014-06-17
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-10
    相关资源
    最近更新 更多