0

I have an app that I want to add an admin page to. I want the admin page to have its own layout seperate from the client layout. With what I have what's the current and 'best' way to implement this?

app.js

import './App.css';
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from './pages/HomePage';
import ItemDetailPage from './pages/ItemDetailPage';
import Header from './components/Header';
import Footer from './components/Footer';
import CollectionPage from './pages/CollectionPage';
import AdminPage from './pages/AdminPage';

function App() {
  return (
    <Router>
      {/* Admin app routes */}
        {/* <Route exact path="/admin" component={AdminPage}/> */}
      {/* Client app routes */}
      <div className="app">
        <Header />
        <Switch>
          <Route exact path="/" component={HomePage}/>
          <Route exact path="/item/:itemID" component={ItemDetailPage}/>
          <Route exact path="/collections/:collection" component={CollectionPage}/>
        </Switch>
        <Footer />
    </div>
    </Router>
    
  );
}

export default App;

HOC

export default function ClientLayoutHOC(props) {
    const {component: Component, ...rest} = props;
    return (
        <div className="app">
            <Header />
                {/*<Component {...rest}/> */}
                {props.children}
            <Footer />
        </div>
    )
}

I found this. Should I create an AdminLayout and ClientLayout components and filter the pages through?

Mint
  • 526
  • 4
  • 18

1 Answers1

2

You could create a High Order Component and add it to your non-admin pages like this: The HOC can contain your div wrapper and the Header and Footer.

Then all of your routes stay clean in the Router.Switch

The anonymous functions for HOC, HomePage, ItemDetailPage, and CollectionPage below are meant to be samples of the changes you'll make to those components. The HOC component will be a separate component too.

const HOC = (props) => {
    const {component: Component, ...rest} = props;
    return (
        <div className="app">
            <Header/>
            <Component {...rest}/>
            <Footer/>
        </div>
    )
}

const HomePage = (props) => {
    return (
        <HOC>
            {/* replace with HomePage content*/}
        </HOC>
    )
}

const ItemDetailPage = (props) => {
    return (
        <HOC>
            {/* replace with ItemDetailPage content*/}
        </HOC>
    )
}

const CollectionPage = (props) => {
    return (
        <HOC>
            {/* replace with CollectionPage content*/}
        </HOC>
    )
}

function App() {
    return (
        <Router>
            <Switch>
                {/* Admin app routes */}
                <Route exact path="/admin" component={AdminPage}/>
                {/* Client app routes */}
                <Route exact path="/" component={HomePage} />
                <Route exact path="/item/:itemID" component={ItemDetailPage}/>
                <Route exact path="/collections/:collection" component={CollectionPage}/>
            </Switch>
        </Router>

    );
}

In looking at your added HOC code I would suggest the following changes:

export default function ClientLayoutHOC(props) {
    const {component: Component, children, ...rest} = props;
    return (
        <div className="app">
            <Header />
                <Component {...rest}>
                    {children}
                </Component>
            <Footer />
        </div>
    )
}
Scott Gnile
  • 269
  • 1
  • 7
  • Can you take a look at my HOC; if I uncomment it breaks. – Mint Jan 10 '21 at 17:07
  • use `{props.children}` instead – Mint Jan 10 '21 at 17:24
  • I am not sure of what children you are supplying to your components, e.g. HomePage, ItemDetailPage, and CollectionPage in your example are all Route components with empty 'children' properties. When your component ends with a /> you aren't supplying children. In order for there to be children you need to have markup between the opening and closing tag of the component's markup. e.g. {/*This is where you add children*/}. – Scott Gnile Jan 11 '21 at 13:36