我目前正在关注Robin Wieruch的著作《用Firebase进行反应的道路》。我的问题是,当我刷新从Context API使用的页面时,Firebase的authUser变为空。
这是我的app.js
import Navigation from './Navigation';
import LandingPage from './Landing';
import AccountPage from './Account';
import withAuthentication from './withAuthentication';
import * as routes from '../constants/routes';
const App = () =>
<Router>
<div>
<h3 className="alt-h3" style={{textAlign: "center"}}>Soundyladder</h3>
<Navigation />
<hr/>
<Route
exact path={routes.LANDING}
component={LandingPage}
/>
<Route
exact path={routes.ACCOUNT}
component={AccountPage}
/>
</div>
</Router>
export default withAuthentication(App);
如您所见,app.js使用的是高级组件。
withAuthentication.js:
import AuthUserContext from './AuthUserContext';
const withAuthentication = (Component) => {
class withAutnetication extends React.Component {
constructor(props) {
super(props);
this.state = {
authUser: null
};
}
componentDidMount() {
firebase.auth.onAuthStateChanged(authUser => {
authUser != null ? this.setState({ authUser }) : this.setState({ authUser: null });
});
}
render() {
const { authUser } = this.state;
console.log(this.state);
return (
<AuthUserContext.Provider value={authUser}>
<Component { ...this.props } />
</AuthUserContext.Provider>
)
}
}
return withAutnetication;
}
export default withAuthentication;
正如您在此处看到的那样,我提供了Context API,以便App.js下的每个组件都可以从中使用它。
这是AuthUserContext:
import React from 'react';
const AuthUserContext = React.createContext(null);
export default AuthUserContext;
问题是,当我访问帐户页面,然后刷新页面时,authUser变为空。
Account.js:
const AccountPage = () =>
<AuthUserContext.Consumer>
{authUser =>
<div>
<h1>Account: {authUser.email}</h1>
<PasswordForgetForm />
<PasswordChangeForm />
</div>
}
</AuthUserContext.Consumer>
export default AccountPage;
但是,当我在LandingPage上并刷新页面时,authUser不会为空。
这是我的目标网页:
const LandingPage = () =>
<div>
<h1>Landing Page</h1>
</div>
export default LandingPage;
但是,如果我尝试从登录页面的Context API中使用authUser,就像在帐户页面中一样,则会遇到相同的错误:authUser变为null。
Context API似乎有问题吗?
答案 0 :(得分:0)
我不确定“使用Firebase做出反应的道路”一书中的身份验证策略是什么,但是可以通过这种方式简单地解释您遇到的问题。
在第一次渲染时(刷新页面后),React首先安装所有可用内容。然后,它在您的componentDidMount
HOC中触发withAuthentication
方法。
这意味着,在第一次渲染时(刷新页面后立即),上下文值authUser
为null
。
React引发错误(这是正确的吗?),然后停止执行。因此从未到达您的componentDidMount
在HOC。
Cannot read property 'email' of null
在这里,React不会停止执行,因为它可以呈现所有内容。然后将触发componentDidMount
在HOC和火力获取用户(异步)。通过在导航到用户已被加载的“帐户页面”,因此你authUser
是不再null
。
再次不知道什么样的验证策略的书提供,而是去解决这个问题,你可以简单地做这些方针的东西在你的HOC
render() {
const { authUser } = this.state;
if (!authUser) {
return null;
}
return (
<AuthUserContext.Provider value={authUser}>
<Component { ...this.props } />
</AuthUserContext.Provider>
)
}
或者您可以像这样在“帐户页面”中添加支票
<h1>Account: {authUser ? authUser.email : null}</h1>
一个非常粗糙的例子可以发现in this codesandbox。我用setInterval
代替火力AUTH方法。让我知道它有助于解决问题。