1
votes

I'm working on a React web app to route different pages. Using React Router

Requirement: Totally 2 major parent routes namely (Customer and Admin) So when user hits ex.: localhost:3000 it should default to homepage (Customer Component) and localhost:3000/admin route to (Admin Page).

Problem: Either I'm only able to route all child components of Customer (or) Admin. Both are not working as properly.

Currently What is Working?

  • localhost:3000 - Loading Home page
  • localhost:3000/sale - Blank page (need to fix)
  • localhost:3000/sale/product - Blank page (need to fix)
  • localhost:3000/admin - Loading Admin page
  • localhost:3000/admin/all-products - Loading Product List page
  • localhost:3000/admin/add-product - Loading Product Detail page

Files: Index.js

ReactDOM.render(
    <BrowserRouter basename='/'>
        <App />
    </BrowserRouter>,
    document.getElementById("root")
);

App.js

class App extends Component {
    render() {
        return (
            <Switch>
                <Route exact path='/' component={Customer} />
                <Route path='/admin' component={Admin} />
            </Switch>
        );
    }
}

Customer.js

class Customer extends Component {
    render() {
        return (
            <div>
                <Header />
                <div className='container mainContent'>
                    <Breadcrumbs />
                    <Switch>
                        <Route path='/' component={Home} />
                        <Route path='/sale' component={ProductList} />
                        <Route path='/sale/product' component={ProductDetails} />
                    </Switch>
                </div>
                <Footer />
            </div>
        );
    }
}

Admin.js

class Admin extends Component {
    render() {
        return (
            <div className='container-fluid'>
                <div className='row'>
                    <ul className='sidebar-submenu '>
                        <li>
                            <NavLink to='/admin/all-products' activeClassName='active'>All Products</NavLink>
                        </li>
                        <li>
                            <NavLink to='/admin/add-product' activeClassName='active'>>Create Product</NavLink>
                        </li>
                    </ul>
                    <div className='col-md-10 admin-content'>
                        <Switch>
                            <Route path='/admin/all-products' component={ProductListView} />
                            <Route path='/admin/add-product' component={ProductListCreate} />
                        </Switch>
                    </div>
                </div>
            </div>
        );
    }
}
2

2 Answers

2
votes
  1. First, let go through this one:
localhost:3000/sale - Blank page (need to fix)
localhost:3000/sale/product - Blank page (need to fix)

The reason is at App.js file, you have the exact prop declared on this line:

<Route exact path='/' component={Customer} />

Which results in the nested routes after /, for example, /sale or /sale/product is not working.

Have you realized it already? Why /admin/all-products or /admin/add-product route is working fine? Because you dont have the exact prop declared on this line:

<Route path='/admin' component={Admin} />

So please remove the exact prop in Customer route to get it work!

  1. Second, IMO, you should seperate your Customer and Admin routes from the very beginning. By seperate, I mean you have better authenticate your workflow properly. Please have a look at this: react-router auth-workflow

A Customer should not have the right to view the Admin routes.


Update 1 from Hem's reply:

But /admin and its child routes are goes to blank page.

Keep in mind that you are using Switch component inside App.js. Just like normal switch/case, it will match the very first path (case for normal switch/case) from top to bottom.

So for your case:

<Switch>
 <Route path='/' component={Customer} /> // <- Have no exact here
 <Route path='/admin' component={Admin} />
</Switch>

Because the very first path in Switch is /, so it always goes to the Customer route regardlessly. And /admin is a nested route of /, so it could never reach the Admin route.

Then if add exact to <Route path='/' component={Home} /> able to switch to /sale page and same for /sale/product

Yes, like I said before, because you got rid of the exact prop in the Customer route at App.js. Both /sale & /sale/product are nested routes of /, both ProductList & ProductDetails are nested components inside Customer. It doesnt matter the exact is added in the Home route or not.

IMO, you have better clear your routing layer in advance:

  1. First layer App: /
  2. Second layer Main (nested routes inside App): / for Customer, /admin for Admin
  3. Third layer Pages (nested routes inside Main): /sale, /admin/all-products
  4. Fourth layer Nested Pages (nested routes inside Pages): /sale/product
0
votes

Try this App.js

  class App extends Component {
    render() {
        return (
            <Switch>
                <Route path='/' component={Customer} />
                <Route path='/admin' component={Admin} />
            </Switch>
        );
    }
}

customer.js

 class Customer extends Component {
render() {
    return (
     <BrowserRouter>
        <div>
            <Header />
            <div className='container mainContent'>
                <Breadcrumbs />
                <Switch>
                    <Route exact path='/' component={Home} />
                    <Route exact path='/sale' component={ProductList} />
                    <Route exact path='/sale/product' component={ProductDetails} />
                </Switch>
            </div>
            <Footer />
        </div>
     </BrowserRouter>
    );
  }
}

admin.js

 class Admin extends Component {
    render() {
        return (
           <BrowserRouter>
            <div className='container-fluid'>
                <div className='row'>
                    <ul className='sidebar-submenu '>
                        <li>
                            <NavLink to='/admin/all-products' activeClassName='active'>All Products</NavLink>
                        </li>
                        <li>
                            <NavLink to='/admin/add-product' activeClassName='active'>>Create Product</NavLink>
                        </li>
                    </ul>
                    <div className='col-md-10 admin-content'>
                        <Switch>
                            <Route exact path='/admin/all-products' component={ProductListView} />
                            <Route exact path='/admin/add-product' component={ProductListCreate} />
                        </Switch>
                    </div>
                </div>
            </div>
           </BrowserRouter>
        );
    }
}

import {BrowserRouter} from 'react-router-dom' in both app.js and customer.js file