0

I am currently experimenting with the use of React Router on the website I am building. I came across the use of React Router in order to navigate through my website, and also do other things like read parameter values etc. However, I find it to be slightly confusing. You see, on my administrator login page, the router only works some times - but I haven't really figured out when and when not. I am using this.props.history.push('/admin/dashboard'), which I believe is the correct way of doing it. This is currently my setup in index.js where i have all my routes:

import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import './css-styling/styling.css'
import Frontpage from './Frontpage';
import { BrowserRouter, Route, Router, Switch, Link, NavLink } from 'react-router-dom';
import AdminLogin from './Admin-Login';
import AdminWelcome from './Admin-Welcome';
import Authentication from './components/Authentication';

const websiteRoutes = (
    <Router history={history}>
        <div>
            <Switch>
                <Route path="/" component={Frontpage} exact={true}/>
                <Route path="/admin" component={AdminLogin} exact={true}/>
                <Authentication props={this.props}>
                <Route path="/admin/welcome" component={AdminWelcome} exact={true}/>
                </Authentication>
            </Switch>
        </div>
    </Router>
);

var appRoot = document.getElementById('root');
registerServiceWorker();
ReactDOM.render(websiteRoutes, appRoot);

And each 'component' has its structure like this:

import React from 'react';
import ReactDOM from 'react-dom';
import AdminHeader from './components/Admin-Header';
import AdminPanelLogin from './components/Admin-Panel-Add-News';
import history from './components/History';

class AdminLogin extends React.Component{

    render() {
        return(
            <div>
            <AdminHeader />
            <AdminPanelLogin />
            </div>
        );
    }

}

export default AdminLogin;

What seem to be the problem here? I have tried a lot of different solutions, without having any luck. One of them was creating this 'global history', which you can see that I have imported in my AdminAddNews class.

What is the correct way of using React Router in my case?

By the way; The history.push happens inside my AdminPanelLogin component, where the code looks like this:

import React from 'react';
import ReactDOM from 'react-dom';
import { Icon, Input, Button, Message } from 'semantic-ui-react';
import {auth} from './Firebase';
import {NotificationContainer, NotificationManager} from 'react-notifications';
import { withRouter, Redirect } from 'react-router-dom';
import history from './components/History';


class AdminLogin extends React.Component{

constructor(props){
    super(props);

    this.handleLogin = this.handleLogin.bind(this);
    this.clickLogin = this.clickLogin.bind(this);
    this.performLogin = this.performLogin.bind(this);
}


handleLogin(e){
    this.setState({
        [e.target.name]: e.target.value
    });
}


clickLogin(e){
    e.preventDefault();
    auth.signInWithEmailAndPassword(this.state.email, this.state.password).then(() => {
        this.props.history.push('/admin/dashboard');
    }).catch((error)=> {

    })
}

    render() {
        return (
            <HTMLGOESHERE>
        );
    }
}

export default AdminLogin;
askaale
  • 1,067
  • 1
  • 19
  • 41
  • Possible duplicate of [programmatically-navigate-using-react-router](https://stackoverflow.com/questions/44127739/programmatically-navigate-using-react-router/44128108#44128108) – Shubham Khatri Feb 14 '18 at 12:15
  • please check the duplicate question and I am sure you will understand what is wrong – Shubham Khatri Feb 14 '18 at 12:16
  • @ShubhamKhatri So I need to use withRouter() on every single component on my website? – askaale Feb 14 '18 at 12:19
  • 1
    I suppose it clearly explained in the answer as to when you need to use withRouter, but just to mention the fact, you only need to use withRouter when the component from which you are trying to do navigation is not receveing the Router props – Shubham Khatri Feb 14 '18 at 12:19
  • @ShubhamKhatri I see, thanks. Is it any particular method of determining this beforehand, instead of having to manually check with console.log? – askaale Feb 14 '18 at 12:22
  • You need to check you implementation and then you can be certain. – Shubham Khatri Feb 14 '18 at 12:23
  • Consider upvoting the answer if it helped – Shubham Khatri Feb 14 '18 at 12:23
  • @ShubhamKhatri It's still not working, and just 'in case' I exported every single class/component using withRouter. – askaale Feb 14 '18 at 12:28
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165147/discussion-between-shubham-khatri-and-askaale). – Shubham Khatri Feb 14 '18 at 12:30

2 Answers2

2

Few things, that you need to correct,

First: In your Routes you have passed history but you have not created a custom history anywhere. You can simply use BrowserRouter for now.

Second: Write your authentication component as Wrapper to your Routes instead of using your Routes as children to it

Authentication:

const PrivateRoute = (props) => {
    const userKey = Object.keys(window.localStorage)
  .filter(it => it.startsWith('firebase:authUser'))[0];
const user = userKey ? JSON.parse(localStorage.getItem(userKey)) : undefined;
   if (user) {
      return <Route {...props} />
   } else {
      return <Redirect to='/admin'/>
   }
}

export default PrivateRoute;

Now you Routes can be

import { BrowserRouter as Router, Route, Router, Switch } from 'react-router-dom';

import Authentication from './Authentication';
const websiteRoutes = (
    <Router>
        <div>
            <Switch>
                <Route path="/" component={Frontpage} exact={true}/>
                <Route path="/admin" component={AdminLogin} exact={true}/>
                <Authentication path="/admin/welcome" component={AdminWelcome} exact={true}/>
            </Switch>
        </div>
    </Router>
);

Apart from this check how to Programmatically Navigate with react-router

Shubham Khatri
  • 211,155
  • 45
  • 305
  • 318
  • This completely solved my problem. It was a problem with my Authentication after all. Thank you again, you saved me a lot of headache. +1! – askaale Feb 14 '18 at 13:29
1

Actually, you have to use browserHistory, which is a function of react-router.I hope following snippet will help you,

Import react-router in your index.js

import {Router, Route, browserHistory} from 'react-router';

ReactDOM.render(
  <Router history={browserHistory} >
    <Route path="/admin/somethingZero" component={somethingZero} />
    <Route path="/admin/somethingOne" component={somethingOne}/>
  </Router> , document.getElementById("root")
)

you can navigate between the components, by using browserHistory.push function

clickLogin(){
    browserHistory.push('/admin/dashboard')
  }

Also, go on with this tutorial, it will give better understanding of routers.

Thananjaya S
  • 756
  • 2
  • 9
  • 27