状态树中的部分授权对象未定义

时间:2018-07-25 20:34:34

标签: redux-saga polymer-3.x

我目前正在为个人项目开发身份验证系统。我使用了经过稍微修改的Polymer PWA入门套件(在这里:https://github.com/Protoss78/pwa-firebase-saga-kit)。此版本与Polymer团队的普通版本之间唯一的功能区别在于,它使用Redux Saga中间件而不是Thunk。

我遇到的问题与存储在auth节中的user对象有关,该对象最初是在加载入口文件并位于路径http://127.0.0.1:8081/时定义的,但是当路径更改为http://127.0.0.1:8081/profile状态树的auth部分在Redux DevTools中完全消失,当尝试通过_stateChanged()将状态值绑定到this.user = state.auth.user中的组件属性时,记录以下错误到控制台:Uncaught TypeError: Cannot read property 'user' of undefined at HTMLElement._stateChanged (my-profile.js:20)。我正在尝试使用user对象的值(为null或某个值)来确定要渲染的模板。

在初始加载时,_firstRendered()函数如下所示:

_firstRendered() {
store.dispatch(watchAuthState());
installRouter((location) => 
store.dispatch(updatePage(window.decodeURIComponent(location.pathname))));
installOfflineWatcher((offline) => store.dispatch(updateOffline(offline)));  
}

相关的部分是watchAuthState()动作的分派,如下所示:

// This action triggers the saga
export const watchAuthState = () => {
  return {
    type: WATCH_AUTH_STATE
  };
};

此动作触发以下传奇:

function* watchAuthState() {
    const channel = yield call(doWatchAuthState);
    try {
      while (true) {
        const payload = yield take(channel);
        if (payload && payload.user) {
          yield put(setUser(payload.user));
        } else {
          yield put(setUser(null));
        }
      }
    } catch (error) {
      console.log(error);
    }
  }

  function doWatchAuthState() {
    return eventChannel(emit => {
      let stateChangedEvent = user => emit({user: user});
      firebase.auth().onAuthStateChanged(stateChangedEvent)

      const unsubscribe = () => {
      // Normally one would want to close the channel, but here we are 
      returning an empty function to keep the channel open
      };
      return unsubscribe;
    });
  }

然后,观察者传奇将分派setUser()动作,其有效载荷为null或通道发出的对象。操作如下:

export const setUser = (user) => {
  return {
    type: SET_USER,
    user
  };
};

我的auth reducer看起来像这样:

import { SET_USER } from '../actions/auth.js';

const auth = (state = {}, action) => {
  switch (action.type) {
    case SET_USER:
      return {
        ...state,
        user: action.user
      };
    default:
      return state;
  }
};

export default auth;

到目前为止,据我所知,一切正常。在http://127.0.0.1:8081/上,一切正常,并且Redux DevTools如果有用户登录,则在状态树中显示Firebase用户对象,如果未登录,则显示null。

我有一个my-login-form.js文件,当URL设置为上述URL时显示。我已经排除了_render()函数以节省空间,但这是my-login-form.js的样子:

import {LitElement, html} from '@polymer/lit-element';
import { connect } from 'pwa-helpers/connect-mixin.js';

// Bring in Redux store
import { store } from '../store.js';

// Bring in needed actions
import { signIn, signOut, emailSignup } from '../actions/auth.js'

// Lazy load auth reducer
import auth from '../reducers/auth.js';

store.addReducers({
  auth
});

class MyLoginForm extends connect(store)(LitElement) {

  constructor() {
    super();
    this.user = null;
  }

  ready(){
    // If you override ready, always call super.ready() first.
    super.ready();
  }

  static get properties() {
    return {
      user: Object
    }
  }

  _stateChanged(state) {
    this.user = state.auth.user;
  }

_onEmailSignup() {
    var email = this.shadowRoot.querySelector("#signup-email").value;
    var password = this.shadowRoot.querySelector("#signup-password").value;

    store.dispatch(emailSignup(email, password));
  }

  _onSignIn() {
    store.dispatch(signIn());
  }

  _onSignOut() {
    store.dispatch(signOut());
  }
  }

window.customElements.define('my-login-form', MyLoginForm);

登录和注销也可以正常进行,将用户删除或添加到该状态。

将路线设置为http://127.0.0.1:8081/profile时显示的组件如下:

import { html } from '@polymer/lit-element';
import { PageViewElement } from './page-view-element.js';
import { SharedStyles } from './shared-styles.js';
import { connect } from 'pwa-helpers/connect-mixin.js';

// This element is connected to the redux store.
import { store } from '../store.js';

class MyProfile extends connect(store)(PageViewElement) {
  _render(props) {
    if(props.signedIn) {
    return html`
     <p>Hey Garren!</p>
    `;
    } else {
    return html`<p>Not logged in</p>`;
    }
  }

  static get properties() { return {
    // This is the data from the store.
    user: Object,
  }}

  // This is called every time something is updated in the store.
  _stateChanged(state) {
    this.user = state.auth.user;
  }
}

window.customElements.define('my-profile', MyProfile);  

这是我发生问题的地方。每当我尝试加载此组件时,我都会在控制台中看到错误消息。如您所见,我要做的就是根据状态中对象的值来决定要呈现的内容。我花了很多时间研究可能导致问题的原因,但是没有任何事情可以帮助我弄清楚发生了什么情况。我什至在相同回购的干净克隆上实现了相同的功能,并且工作正常。我还是Redux和Polymer的新手,所以我意识到答案可能很明显,但我很想念它。但是,任何帮助将不胜感激!谢谢!

0 个答案:

没有答案