首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用NGXS修补存储的更新状态。我一直看到类型错误:无法冻结

无法使用NGXS修补存储的更新状态。我一直看到类型错误:无法冻结
EN

Stack Overflow用户
提问于 2021-03-31 16:29:14
回答 1查看 219关注 0票数 0

我正在使用一个基本的Angular 11应用程序,它实现了身份验证(使用AWS Cognito & Amplify)。我在这里尝试做的事情非常简单。我使用内置的AWS Amplify方法进行身份验证。我正在使用NGXS来存储与身份验证相关的项目,如令牌、用户信息等。

代码语言:javascript
复制
import { State, Action, StateContext, Selector } from '@ngxs/store';
import { AuthStateModel, defaultAuthState } from './auth.model';
import {
  LoginAction,
  AuthenticationCheckAction,
  LogoutAction,
} from './auth.actions';
import { Auth } from 'aws-amplify';
import { environment } from 'src/environments/environment';
import { Injectable } from '@angular/core';
import { updateItem } from '@ngxs/store/operators';

@State<AuthStateModel>({
  name: 'authState',
  defaults: defaultAuthState,
})
@Injectable()
export class AuthState {
  cognitoClientId = environment.cognitoClientId;
  cognitoCallbackURL = environment.cognitoCallbackURL;
  cognitoDomainName = environment.cognitoDomainName;
  loginurl = `https://${this.cognitoDomainName}/login?response_type=code&client_id=${this.cognitoClientId}&redirect_uri=${this.cognitoCallbackURL}`;

  @Selector()
  static getIsLoggedIn(state: AuthStateModel) {
    console.log('from getIsLoggedIn selector =>', state);
    return state.isLoggedIn;
  }

  @Action(LoginAction)
  login() {
    window.location.assign(this.loginurl);
  }

  @Action(AuthenticationCheckAction)
  checkLogin({ getState, patchState }: StateContext<AuthStateModel>) {
    const state = getState();
    Auth.currentAuthenticatedUser()
      .then((currentUser) => {
        const isLoggedIn = true;
        const username = currentUser?.attributes?.name;
        patchState({
          currentUser,
          isLoggedIn,
          username,
        });
      })
      .catch((err) => console.log(err));
    return;
  }

  @Action(LogoutAction)
  logout({ patchState }: StateContext<AuthStateModel>) {
    Auth.signOut()
      .then((data) => {
        console.log(data);
        patchState(defaultAuthState);
      })
      .catch((err) => console.log(err));

    return;
  }
}

除了命中checkLogin函数内的patchState方法之外,一切都正常工作,它在浏览器控制台中抛出以下错误:-

代码语言:javascript
复制
TypeError: Cannot freeze
    at Function.freeze (<anonymous>)
    at deepFreeze (ngxs-store.js:1869)
    at ngxs-store.js:1884
    at Array.forEach (<anonymous>)
    at deepFreeze (ngxs-store.js:1874)
    at ngxs-store.js:1884
    at Array.forEach (<anonymous>)
    at deepFreeze (ngxs-store.js:1874)
    at ngxs-store.js:1884
    at Array.forEach (<anonymous>)

奇怪的是,如果我注释掉pathState()方法中提到的currentUser,错误就会消失。因此,更新状态中的对象是有问题的。

ngxs-store.js文件的此错误中引用的行包含以下代码。1869处的行是开头的Object.freeze(o)行:-

代码语言:javascript
复制
const deepFreeze = (/**
 * @param {?} o
 * @return {?}
 */
(o) => {
    Object.freeze(o);
    /** @type {?} */
    const oIsFunction = typeof o === 'function';
    /** @type {?} */
    const hasOwnProp = Object.prototype.hasOwnProperty;
    Object.getOwnPropertyNames(o).forEach((/**
     * @param {?} prop
     * @return {?}
     */
    function (prop) {
        if (hasOwnProp.call(o, prop) &&
            (oIsFunction ? prop !== 'caller' && prop !== 'callee' && prop !== 'arguments' : true) &&
            o[prop] !== null &&
            (typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
            !Object.isFrozen(o[prop])) {
            deepFreeze(o[prop]);
        }
    }));
    return o;
});

不够精明,不能理解这里发生了什么。这是一个修补状态的简单尝试。状态模型如下:

代码语言:javascript
复制
export class AuthStateModel {
  isLoggedIn: Boolean;
  currentUser: Object;
  username: String;
}

export const defaultAuthState: AuthStateModel = {
  isLoggedIn: false,
  currentUser: {},
  username: '',
};

我能做些什么来让它正常工作吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-31 21:07:09

有时,当我遇到像这样的问题时,我不能更改对象,我只是克隆它。我通常使用lodash的cloneDeep来完成以下操作:

代码语言:javascript
复制
patchState({
  currentUser: _.cloneDeep(currentUser),
  isLoggedIn,
  username,
});

另外,试着保持你的状态可序列化。不熟悉AWS Cognito & Amplify,但是如果currentUser是一个绑定了方法和其他成员的对象,则我不会将currentUser对象存储在状态中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66884199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档