12

In reference to the unresolved question (as a final conclusion)

I am also getting the same issue.

https://reacttraining.com/react-router/web/guides/quick-start promotes react-router-dom

Also, people find better to list down routes in one file rather inside components.

Something referred: https://github.com/ReactTraining/react-router/tree/master/packages/react-router-config

Something working (mostly):

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


export const Routes = () => (
  <Router>
    <div>
      <Switch>
        <Route exact path="/login" component={Login}/>
        <MainApp path="/">
          <Route path="/list" component={List}/>
          <Route path="/settings" component={Settings}/>
        </MainApp>
        <Route path="*" component={PageNotFound}/>
      </Switch>
    </div>
  </Router>
)

Something not working: site.com/SomeGarbagePath shows the <MainApp> I think.
<Route path="*" component={PageNotFound}/>

Update

/ - Home - parent of all (almost)
/List - inside home
/Settings - inside home
/Login - standalone
/Users - inside home, For now just showing itself. It has further pages.
/User/123 - inside user with /:id
/User/staticUser - inside user with static route
/garbage - not a route defined (not working as expected)
Community
  • 1
  • 1
Masood
  • 145
  • 2
  • 6
  • It isn't clear what you are asking. Please give some examples of what your routes should be, and how you want your routes to behave. – Todd Chaffee Apr 10 '17 at 18:26
  • @ToddChaffee Login page is standalone. The `/` wants to render header, footer and some other content in between header and footer. Content is based on the router path (e.g `list` for `/list` and `settings` component for `/settings`. If no route matches, its a `pageNotFound` – Masood Apr 10 '17 at 18:38
  • @Masood - did you find any solution for this? For some reason the answer below doesn't work for me. – galvan Nov 07 '18 at 14:19

2 Answers2

10

This is one way of doing what you described (note there are other ways of handling layouts directly in your React Components). In order to keep the example simple, the other components (<Home>, <List> etc.) are created as purely functional components with no properties or state but it would be trivial to put each one in its own file as a proper React component. The example below is complete and will run.

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

class App extends Component {
  render() {

    const Header = () => <h1>My header</h1>;
    const Footer = () => <h2>My footer</h2>;
    const Login = () => <p>Login Component</p>;    
    const Home = () => <p>Home Page</p>;
    const List = () => <p>List Page</p>;
    const Settings = () => <p>Settings Page</p>;
    const PageNotFound = () => <h1>Uh oh, not found!</h1>;

    const RouteWithLayout = ({ component, ...rest }) => {
      return (
        <div>
          <Header />
          <Route {...rest} render={ () => React.createElement(component) } />
          <Footer />
        </div>
      );
    };

    return (
      <Router>
        <div>
          <Switch>
            <Route exact path="/login" component={Login} />
            <RouteWithLayout exact path="/" component={Home} />
            <RouteWithLayout path="/list" component={List} />
            <RouteWithLayout path="/settings" component={Settings} />
            <Route path="*" component={PageNotFound} />
          </Switch>
        </div>
      </Router>    
    );
  }
}

export default App;

This will do the following, which is hopefully what is now described in your question:

  1. /login has no header or footer.
  2. /, /list, and /settings all have the header and footer.
  3. Any route that is not found will display the PageNotFound component, with no header or footer.
Todd Chaffee
  • 6,258
  • 28
  • 39
  • Chafee, A) I do NOT want `/login` to have `Header`. Please let me know what fits my use case. B) I may or many not nest routes for few components and not for others (as shown in example) – Masood Apr 11 '17 at 04:36
  • There is no nesting of routes in your example, or at least it isn't clear. The way you are "nesting" routes, you have `/login` and then `/login/list` and `/login/settings`. What do you really want? Your question is so unclear. You need to give more examples in your question if you want help. Tell us WHY you want to nest routes. What BEHAVIOR are you trying to achieve. If you can tell us that, maybe we can help. – Todd Chaffee Apr 11 '17 at 11:45
  • Todd Chaffee I NEVER stated /login/list. If you observe A) `react-router-dom v4`, Routes have components. B) see `` that does NOT have `/login` route. So the route is NOT `login/list` but its `/list`. This is not `v3`. For more elaboration: see `update` – Masood Apr 11 '17 at 17:22
  • Todd Chaffee, your solution is promising and working! However I wanted some that had routes on a single file, nesting and still with react-router-dom-v4 way. I am accepting your solution as best comparatively so far. Thanks a lot for the great effort! – Masood Apr 13 '17 at 19:17
1

I'll be honest, I'm not entirely sure what you're asking. I'm assuming you're trying to get your "Something not working" example to work.

Something like this,

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


export const Routes = () => (
  <Router>
    <div>
      <Switch>
        <Route exact path="/login" component={Login}/>
        <MainApp path="/">
          <Switch>
            <Route path="/list" component={List}/>
            <Route path="/settings" component={Settings}/>
          </Switch>
        </MainApp>
        <Route component={PageNotFound} /> 
      </Switch>
    </div>
  </Router>
)
Masood
  • 145
  • 2
  • 6
Tyler McGinnis
  • 30,798
  • 16
  • 69
  • 74
  • Thanks for replying but its not working. Its showing the errorpage inside MainApp page (or not at all with placement variations); when garbabe typed link. – Masood Apr 16 '17 at 15:40