当我第一次登录并使用Web应用程序时,我能够检索经过身份验证的用户并从数据库访问该用户的信息。但是,刷新页面后,我立即收到“ TypeError:无法读取null的属性'uid'”。
我可以进行一些调试,看到我最初登录时,身份验证组件的ComponentDidMount()(包裹我的App组件的高阶组件)通过以下方式检查经过身份验证的用户:调用onAuthStateChanged会在获取数据的组件的ComponentDidMount()之前调用。但是,当我刷新时,调用的顺序会切换,并且我的身份验证组件会在之后被调用。我的最终目标是能够获取已登录用户的uid,以便从数据库中获取其数据。
以下是我的withAuthentication组件:
import React from 'react';
import AuthUserContext from './context';
import { withFirebase } from '../Firebase';
const withAuthentication = Component => {
class WithAuthentication extends React.Component {
constructor(props) {
super(props);
this.state = {
authUser: null,
};
}
componentDidMount() {
this.listener = this.props.firebase.auth.onAuthStateChanged(
authUser => {
authUser
? this.setState({ authUser })
: this.setState({ authUser: null });
},
);
}
componentWillUnmount() {
this.listener();
}
render() {
return (
<AuthUserContext.Provider value={this.state.authUser}>
<Component {...this.props} />
</AuthUserContext.Provider>
);
}
}
return withFirebase(WithAuthentication);
};
export default withAuthentication;
然后,我使用这个高阶组件包装我的根App组件,如下所示:
const App = () => (
<Router>
<Switch>
{indexRoutes.map((prop, key) => {
return <Route exact path={prop.path} component={prop.component} key=
{key} />;
})}
</Switch>
</Router>
);
export default withAuthentication(App);
然后将此根应用程序组件呈现在我的根index.js文件中
ReactDOM.render(
<FirebaseContext.Provider value={new Firebase()}>
<App />
</FirebaseContext.Provider>,
document.getElementById('root'),
);
答案 0 :(得分:0)
这是因为,当您登录时,首先authUser
为空,然后登录并为authUser
分配了用户对象,并且在其他组件中使用了authUser.uid
,并且效果很好。
下一次重新加载页面时,登录页面不会打开,因为您已经登录,因此会呈现使用authUser.uid
的其他组件。默认情况下,authUser
为null,因为默认状态为null
,而onAuthStateChanged
是异步的,这意味着它不会立即执行,因此使用authUser.uid
的其他组件会产生错误。在使用uid
的组件中,您可以执行以下操作:
authUser ? authUser.uid : ''