我应该在哪里检查用户会话是否仍处于活动状态?

时间:2018-06-28 14:09:17

标签: reactjs firebase redux react-router

我在检查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,我应该在哪里检查它?

1 个答案:

答案 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中或类似的东西(我不知道)之后,似乎无法设置单个路由。