How To Redirect to Login Page Before Entering Index Route in ReactJS + REDUX

23,645

Solution 1

Thanks alot Dat Tran, now i just change my index.js code into this :

import React from "react";
import ReacrDOM from "react-dom";
import {Router, Route, IndexRoute, hashHistory, browserHistory} from "react-router"
import {Provider} from "react-redux";
import {login_check, show_log, fakeLogin} from "./actions/logActions";

import store from "./store";
import Layout from "./pages/Layout";
import Dashboard from "./pages/Dashboard";
import Login from "./pages/login/index";
import User from "./pages/user/index";
import Pemain from "./pages/pemain/index";

const app = document.getElementById("app");

function requireLogin() {
    const {user_id, session_key}=store.getState().logReducer;
    store.dispatch(login_check({user_id: user_id, session_key: session_key}))
    const {logged_in}=store.getState().logReducer;
    if (!logged_in) {
        browserHistory.push('#/login');
        hashHistory.push('/login');
    }
}

ReacrDOM.render(
    <Provider store={store}>
        <Router history={hashHistory}>
            <Route path="/login" component={Login}/>
            <Route path="/" component={Layout} onEnter={requireLogin}>
                <IndexRoute component={Dashboard}/>
                <Route path="user" component={User}/>
                <Route path="pemain" component={Pemain}/>
            </Route>
        </Router>
    </Provider>
    , app);

and my login.js into this :

import React from "react";
import {connect} from "react-redux";
import {login} from "../../actions/logActions";
import {browserHistory, hashHistory} from "react-router"

@connect((store) => {
    return {
        session_key: store.logReducer.session_key,
        user_id: store.logReducer.user_id,
        error_message: store.logReducer.error_message,
        logged_in: store.logReducer.logged_in,
        log_error: store.logReducer.log_error,
    }

})

export default class index extends React.Component {

    login(event) {
        event.preventDefault();
        this.props.dispatch(login(this.refs.email_pemain.value, this.refs.password.value));
    }

    showError() {
        if (this.props.log_error) {
            return (
                <div className="error_message alert-danger">
                    {this.props.log_error}
                </div>
            );
        }

        return (<div>

        </div>);
    }


    render() {

        if (this.props.logged_in) {
            browserHistory.push('#/');
            hashHistory.push('/');
        }

        return (
            <div className="container">
                <div className="login-box">
                    <div className="header">
                        login
                    </div>
                    <div className="login-form-wrapper">
                        <form onSubmit={this.login.bind(this)}>
                            <div>
                                <label for="email_pemain">Email</label>
                                <input className="form-control" id="email_pemain" name="email_pemain" type="text"
                                       ref="email_pemain"/>
                            </div>
                            <div>
                                <label for="password">Password</label>
                                <input className="form-control" id="password" name="password" type="password"
                                       ref="password"/>
                            </div>
                            <br/>
                            <br/>
                            <input className="btn btn-info pull-right" type="submit" value="Login"/>
                            <div className="clearfix">

                            </div>
                            {this.showError()}
                        </form>
                    </div>
                </div>
            </div>
        );
    }
}

and it works now...and thank you very much @Dat Tran

Solution 2

The property onEnter has been removed since react-router-4 , now you should use the render method instead, here's an example how to do a redirect :

<Route exact path="/home" render={(props) => (
  isUserLoggedIn() ? (
    <Home {...props} />
  ) : (
    <Redirect to="/login"/>
  )
)}/>

Solution 3

You need to implement OnEnter props in the routers. Check this project for the whole sollutions: React Redux Universal Hot Example

Share:
23,645
vidihermes
Author by

vidihermes

working and still learning, too much to learn, but i love it

Updated on October 17, 2020

Comments

  • vidihermes
    vidihermes over 3 years

    I am really new to react, now i want to implement a login page before entering to any routes, i am currently using :

    React : 15.4.2, React-DOM : 15.4.2, React-Redux : 5.0.4, and i am using webpack and es2015 as my preset.

    i have done so much googling, but i still does not found any solution, here is current source code : for index.js :

    import React from "react";
    import ReacrDOM from "react-dom";
    import {Router, Route, IndexRoute, hashHistory} from "react-router"
    import {Provider} from "react-redux";
    
    import store from "./store";
    import Layout from "./pages/Layout";
    import Dashboard from "./pages/Dashboard";
    import Login from "./pages/login/index";
    import User from "./pages/user/index";
    import EnsureLoggedIn from "./EnsureLoggedIn";
    
    const app = document.getElementById("app");
    
    ReacrDOM.render(
        <Provider store={store}>
            <Router history={hashHistory}>
                <Route path="/login" component={Login}/>
                <Route component={EnsureLoggedIn}>
                    <Route path="/" component={Layout}>
                        <IndexRoute component={Dashboard}/>
                        <Route path="user" component={User}/>
                    </Route>
                </Route>
            </Router>
        </Provider>
        , app);
    

    Here is my Dashboar Component :

    import React from "react";
    import {connect} from "react-redux";
    
    @connect((store) => {
        return {
    
        }
    })
    
    export default class Dashboard extends React.Component {
    
        componentWillMount() {
    
        }
    
        render() {
            return (
                <div>
                    <h3>Dashboard</h3>
                    <hr/>
                </div>
            );
        }
    }
    

    and here is my EnsureLoggedIn File :

    import React from "react";
    import {browserHistory} from 'react-router';
    import {connect} from "react-redux";
    import {login_check, show_log} from "./actions/logActions";
    
    @connect((store) => {
        return {
            session_key: store.logReducer.session_key,
            user_id: store.logReducer.user_id,
            error_message: store.logReducer.error_message,
            logged_in: store.logReducer.logged_in
        }
    })
    
    
    export default class EnsureLoggedIn extends React.Component {
        componentDidMount() {
    
            if (!this.isLoggedIn()) {
                browserHistory.push('#/login');
            }
        }
    
        isLoggedIn() {
            this.props.dispatch(show_log());
            var account = {user_id: this.props.user_id, session_key: this.props.session_key};
            this.props.dispatch(login_check(account));
            if (!this.props.logged_in) {
                return false;
            }
    
            return true;
        }
    
        render() {
            return this.props.children
        }
    }
    

    and here is my logReducer :

    export default function (state = {
        user_id: null,
        session_key: null,
        error_message: null,
        logged_in: false,
        log_error: null,
    }, action) {
    
        switch (action.type) {
            case "LOGIN": {
                var {id, session_key}=action.payload.data.data
                state = {
                    ...state,
                    user_id: id,
                    session_key,
                    error_message: null,
                    logged_in: true,
                    log_error: null
                };
                break;
            }
    
            case "LOGIN_FAILED": {
                state = {
                    ...state,
                    error_message: null,
                    log_error: action.payload.response.data.error.message,
                    logged_in: false
                };
                break;
            }
    
            case "CHECK_LOGIN": {
                state = {...state, error_message: null, logged_in: true};
                break;
            }
    
            case "CHECK_LOGIN_FAILED": {
                state = {
                    ...state,
                    error_message: action.payload.response.data.error.message,
                    log_error: null,
                    logged_in: false
                };
                break;
            }
    
            case "LOGOUT": {
                state = {
                    ...state,
                    user_id: null,
                    session_key: null,
                    error_message: null,
                    log_error: null,
                    logged_in: false
                };
                break;
            }
    
            case "GET_LOG_DATA": {
                state = {...state};
                break;
            }
    
        }
    
        return state;
    }
    

    and this is my logActions file :

    import axios from "axios";
    
    const basicAuth = {
        headers: {"authorization": "Basic dmlkeTpwdmlkeQ=="}
    }
    
    export function login(email = "", password = "") {
        var url = 'http://localhost:8080/dfordatabase/api/api/login';
        return function (dispatch) {
            axios.post(url, {email: email, password: password}, basicAuth)
                .then((response) => {
                    dispatch({type: "LOGIN", payload: response});
                }).catch((error) => {
                dispatch({type: "LOGIN_FAILED", payload: error});
            })
        }
    }
    
    export function login_check(account = {}) {
        var url = 'http://localhost:8080/dfordatabase/api/api/login_check';
        return function (dispatch) {
            axios.post(url, {...account}, basicAuth)
                .then((response) => {
                    dispatch({type: "CHECK_LOGIN", payload: response});
                }).catch((error) => {
                dispatch({type: "CHECK_LOGIN_FAILED", payload: error});
            })
        }
    }
    
    export function show_log() {
    
        return function (dispatch) {
            dispatch({type: "GET_LOG_DATA", payload: null});
        }
    }
    

    the problem is : indeed login page will appear at first when i run the code, but when i fill the credential and logged in, page is not redirect to my index route which is "/", the url has change, but dashboard won't appear, if i refresh the page dashboard appear but, the problem is all state of my log reducer become empty again.

    can anyone tell me where can i find some example of similar development tutorial. Please kindly help me..

  • vidihermes
    vidihermes about 7 years
    where shall i put the "requireLogin" function? since i am using react-redux connect function, it's look quite different when implementing the store,shall i put the "requireLogin" function in my index.js? or anywhere else? and how to write it? please kindly help
  • vidihermes
    vidihermes about 7 years
    thank you very much, i found the solution, by following the example you gave..well it work, i am doing similarly as the example and it works.. thx again