我在检查firebase.auth()。onAuthStateChanged()时遇到问题,以了解是否存在活动会话,因此用户不必多次登录。会话检查可以正常工作,但是会破坏路由器。
我通过以下代码在App.js中实现了它:
import React from 'react';
import { Route } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { auth } from './config/Firebase';
import { isUserLoggedIn } from './actions/Authentication';
import Log from './utils/Log';
import Navigation from './components/Navigation/Navigation';
import HomePage from './components/HomePage/HomePage';
import LoginPage from './components/LoginPage/LoginPage';
class App extends React.Component {
state = {
loading: true
};
componentWillMount = () => {
Log.info('Will mount', 'App.js');
const listener = auth.onAuthStateChanged(user => {
if (user) {
this.props.isUserLoggedIn(user);
Log.info(user, 'App.js. User is set: ');
this.setState({ loading: false });
listener();
} else {
this.props.isUserLoggedIn({});
Log.info('User was deleted', 'App.js');
this.setState({ loading: false });
listener();
}
});
}
render () {
return (
<div>
{this.state.loading === true ?
<h1>Loading</h1>
:
<div>
<Navigation />
<div className="container">
<Route path="/" exact component={HomePage} />
<Route path="/login" component={LoginPage} />
</div>
</div>
}
</div>
)
}
}
App.propTypes = {
isUserLoggedIn: PropTypes.func.isRequired
};
export default connect(null, { isUserLoggedIn })(App);
我的ReactDom.render脏代码如下:
const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)));
ReactDOM.render(
<IntlProvider locale={language} messages={messages[language]}>
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
</IntlProvider>, document.getElementById('root')
);
registerServiceWorker();
isUserLoggedIn是一个操作,如果有活动的会话,该操作将调度当前用户:
import { auth } from '../config/Firebase';
export const USER_LOGGED_IN = 'USER_LOGGED_IN';
export const SET_CURRENT_USER = 'SET_CURRENT_USER';
export const userLoggedIn = user => ({
type: USER_LOGGED_IN,
user
});
export const setCurrentUser = user => ({
type: SET_CURRENT_USER,
user
});
export const login = credentials => dispatch =>
auth.signInWithEmailAndPassword(credentials.email, credentials.password)
.then(user => dispatch(userLoggedIn(user.user)));
export const isUserLoggedIn = (user) => dispatch =>
dispatch(setCurrentUser(user));
我希望应用程序处于“正在加载”状态,直到在redux存储中设置了“用户”对象为止,该存储在安装App.js时由我处理。这正常工作,但是,如果我将{isUserLoggedIn}连接到App.js,则调用不同路由的链接将无法正常工作。如果我手动更改URL,则可以正常工作,但是,如果单击将我链接到其他组件的按钮,则URL会更改,但不会向我显示该组件。从App.js中删除连接线后,链接将再次开始工作。
很明显,这不是检查会话的方法,因为它会中断路由,因此,如果不是App.js,我应该在哪里检查它?
答案 0 :(得分:1)
好吧,我最终解决了它。
我将BrowserRouter移至App.js中,并且在获取登录用户后也更改了所有呈现方式。
render () {
let {loading } = this.state;
if (loading) {
return <h1>Loading</h1>;
} else {
return (
<BrowserRouter>
<div>
<Navigation />
<div className="container">
<Route path="/" exact component={HomePage} />
<Route path="/login" component={LoginPage} />
</div>
</div>
</BrowserRouter>
);
}
}
现在,该应用程序会一直保持加载状态,直到拥有用户数据为止,并且在获取到该数据之后,它会呈现其他所有内容,同时还能够通过链接导航该应用程序。
在BrowserRouter已经在DOM中或类似的东西(我不知道)之后,似乎无法设置单个路由。