【发布时间】:2019-07-04 16:13:09
【问题描述】:
当我第一次登录并使用我的 Web 应用程序时,我能够检索经过身份验证的用户并从数据库中访问该用户的信息。但是,一旦我刷新页面,我就会得到“TypeError:无法读取 null 的属性 'uid'”。
我能够对此进行一些调试,并看到当我最初登录时,我的身份验证组件(这是一个包装我的 App 组件的高阶组件)的 ComponentDidMount(),它通过以下方式检查经过身份验证的用户调用 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'),
);
【问题讨论】:
-
请在codesandbox分享代码
-
我认为正常的顺序是子组件的 ComponentDidMounts 比其父组件运行得早(这是合乎逻辑的,因为您不能说组件在其所有子组件都已安装之前已安装)。我不确定它如何与 HOC 一起使用,但可以相同。我建议将一些
isAuthed布尔值传递给包装的组件,并在那里实现 getDerivedStateFromProps。当此 auth prop 变为 true 时,触发数据获取。 -
@UmairFarooq 刚刚添加到我的代码中
标签: reactjs firebase firebase-authentication