12

I am getting this error tried different ways of routing still no luck.

I have route config file i.e route.js

const Root = ({ store }) => (
    <Provider store={store}>
        <BrowserRouter>
            <div>
                <Route path='/' component={ App }/>  
            </div>
        </BrowserRouter>
    </Provider>
)

Now at App.js

class AppComp extends Component {
    render() {
        const {match} = this.props;
        let navClass = 'active';

        if(this.props.sideClass === "nav-ssh") {
            navClass = "active-ssh"; 
        }

        return (
            <div>
                <div className="container">
                    <div className="main">
                        <Route render={()=><Header sideNavClass={this.props.sideNavClass} />} />
                        <Route render={()=><SideNav navActiveClass={navClass} currentLocation={this.props.location.pathname} />}/>
                        <Redirect to="/home/dashboard" />s
                    </div>
                </div>
            </div>
        );
    }
}

I want to load app always so put it in the highest level and header and sidenav should also gets loaded always so they are inside app.

For any unknown path and for first time load I redirected to /home/dashboard

I understand it must be coming to / twice so this warning.

How can I configure my router to achieve the same and resolve the warning.

Any help would be greatly appreciated.

0

5 Answers 5

25

Use <Switch>, instead of <div> to wrap the routes.

import React from 'react'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
import { LoginScreen, LogoutScreen } from './components'

export default () => (
  <div>
    <Router>
      <Switch>
        <Route path='/login' component={LoginScreen}/>
        <Route path='/logout' component={LogoutScreen}/>
        <Route component={AuthenticatedRoutes}/>
      </Switch>
    </Router>
  </div>
)
1
  • 2
    Adding on to why this works - if you have a bunch of Route children, multiple urls can match, especially if you have a base path, leading to multiple components rendering at once. Using Switch as the parent allows for only one to match (the first child to) so only one component will render at once. See the switch doc for more details.
    – phouse512
    Nov 23, 2018 at 3:43
2

Even I faced similar issue. It was resolved to me when I added exact in Route.Switch also must be added.

<Switch>
  <Route exact path='/' component={ App }/> 
</Switch> 
2

I resolved the issue. Here's a solution.

route.js
<Provider store={store}>
  <BrowserRouter>
    <div>
      <Route path="/" component={ App }/>
    </div>
  </BrowserRouter>
</Provider>

At App.js add a check match.url === window.location.pathname which is always true for initial rendering so '/' redirects to '/home/dashboard'. Adding this condition resolves the redirect warning.

class AppComp extends Component {
  render() {
    const {match} = this.props;
    let 
        shouldRedirect = match.url === window.location.pathname, 
        redirectTo = <Redirect to="/home/dashboard" />;
    let navClass = 'active';
    if(this.props.sideClass === "nav-ssh") {
      navClass = "active-ssh"; 
    }
    return (
      <div>
        <div className="container">
          <div className="main">
            <Route render={()=><Header sideNavClass={this.props.sideNavClass} />} />
            <Route render={()=><SideNav navActiveClass={navClass} currentLocation={this.props.location.pathname} />}/>
            {shouldRedirect && redirectTo}
          </div>
        </div>
      </div>
    );
  }
}

But you will have a limitation now, if user enters some unknown path then it won't redirect to '/home/dashboard' i.e to our default route.

To overcome that limitation you have to add :

<Switch>
  {/*---- your additional routes goes here -----*/}
  <Redirect to="/home/dashboard" />
</Switch>

Add the above code to the components from where you handle rest of the routing. For example for me I have added to Sidenav component.

1

I guess you would configure your Routes like

<Provider store={store}>
    <BrowserRouter>
        <div>
            <Route path="/" component={ App }/>
        </div>
    </BrowserRouter>
</Provider>

and App.js as

class AppComp extends Component {
    render() {
        const {match} = this.props;
        let navClass = 'active';

        if(this.props.sideClass === "nav-ssh") {
            navClass = "active-ssh"; 
        }

        return (
            <div>
                <div className="container">
                    <div className="main">
                        <Route render={()=><Header sideNavClass={this.props.sideNavClass} />} />
                        <Route render={()=><SideNav navActiveClass={navClass} currentLocation={this.props.location.pathname} />}/>
                       <Switch>
                            <Route path='/home/dashboard' component={ Dashboard }/>

                             <Redirect to='/home/dashboard'/>
                       </Switch>
                    </div>
                </div>
            </div>
        );
    }
}
4
  • If I do exactly you suggested then for dashboard no header and sidenav loaded because switch matched the first statement therefore dashboard gets loaded before App (which contains my header and sidenav ) Nov 24, 2017 at 13:58
  • Sorry, Updated the answer Nov 24, 2017 at 14:01
  • Then its always redirecting to /home/dashboard . my other routes are not working anymore, every navlink redirected to /home/dashboard I think because <Redirect to='/home/dashboard'/>. Tried with exact too. But no luck. :-( Nov 24, 2017 at 14:14
  • Can you add how are you using your other routes Nov 24, 2017 at 15:14
0

Had this same issue - was trying to redirect but was getting an error and I believe all you need is switch:

<Route render={()=><Header sideNavClass={this.props.sideNavClass} />} />
  <Switch>
    <Route render={()=><SideNav navActiveClass={navClass} currentLocation={this.props.location.pathname} />}/>
    <Redirect to="/home/dashboard" />
  </Switch>
</Route>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.