我目前正在为个人项目开发身份验证系统。我使用了经过稍微修改的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的新手,所以我意识到答案可能很明显,但我很想念它。但是,任何帮助将不胜感激!谢谢!