Michael Lynch
Michael Lynch

Reputation: 3149

What is the best way to architecture a React template using props children?

I'm using React to build out a single template that is being used by multiple pages. I'm using the idea of containment with props.children to achieve that.

Everything is working fine, but I'm finding it increasingly annoying to instantiate the page component each time, because the template has a lot of required props.

<PageTemplate
  something={true}
  somethingElse={myVar}
  anotherThing={something}>
  <Home />
</PageTemplate>

<PageTemplate
  something={true}
  somethingElse={myVar}
  anotherThing={something}>
  <About />
</PageTemplate>

<PageTemplate
  something={true}
  somethingElse={myVar}
  anotherThing={something}>
  <Products />
</PageTemplate>

As you can see, <Home />, <About /> and <Products /> all live within the <PageTemplate /> component. Again, this works well, but repeating the same props per instance seems redundant. Is there a better approach to this?

Upvotes: 0

Views: 1375

Answers (2)

Mike Rivet
Mike Rivet

Reputation: 106

If you're not making each "page" its own react app then this sounds like something React Router is set up to solve.

If you were to use this you could have one <PageTemplate> component with a <Router> that renders the different pages.

It's markup would probably look like

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

<Router>
    <PageTemplate
        something={true}
        somethingElse={myVar}
        anotherThing={something}
    >
        <Switch>
            <Route path="/about">
                <About />
            </Route>
            <Route path="/products">
                <Products />
            </Route>
            <Route path="/">
                <Home />
            </Route>
        </Switch>
    </PageTemplate>
</Router>

If this <PageTemplate> component is being used in multiple react apps it would probably be made a bit better using higher-order components as previously suggested.

Upvotes: 1

Noah Callaway
Noah Callaway

Reputation: 636

It depends a lot on where those values are coming from. If they're typically hardcoded values (like something={true} in the question) then you can use default values that cover your most common cases.

If the values are coming from the parent that they're on (e.g. myVar and something in the question) then it depends on what those variables are and how they're set.

One potential solution would be to use the Context API (https://reactjs.org/docs/context.html). Something above the PageTemplate could provide myVar and something via the Context through a ContextProvider.

PageTemplate could be modified to take the somethingElse prop, but if it's not provided to get the default value from the context itself.

Then your Products Page might look like this:

<PageTemplate>
   <Products />
</PageTemplate>

Where the something prop is set with a default value, and the somethingElse and anotherThing prop are retrieved from the Context. It's hard to provide a more specific answer without knowing a little about how the myVar and something values are typically being assigned.

Upvotes: 0

Related Questions