Reputation: 117
(Updated for clarity) I have the following structure for my App:
<Layout />
/components/
<Header />
<Navigation />
<Stage />
<Footer />
/pages/
<Home />
<About />
<Contact />
My thinking is to have the <Navigation>
element isolated, and imported into the parent <Header>
(and later, Site Map). All components are then staged into the parent <Layout>
, which is fed into the <div id="root">
The content of my /pages/ Components are successfully called and rendered with the code below. However this page content is rendered inside of my <header>
element, breaking the page hierarchy.
My intention is to have the <Switch>
device render the /pages/ Components within the <Stage>
parent Component.
Any attempt to move the <Switch>
element to the <Stage>
component causes the whole app to not load/render.
import React from 'react';
import {
BrowserRouter as Router, Route, Link, Switch
} from 'react-router-dom';
import Home from './../pages/Home';
import About from './../pages/About';
import Contact from './../pages/Contact';
export default class Navigation extends React.Component {
render() {
return (
<Router>
<div className="navigation">
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
{/*
Below should be repositioned outside of <header>, in Stage component
*/}
<div className="stage">
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Switch>
</div>
</div>
</Router>
)
}
}
My question is: How can I have the Router render the required /page/ Components inside my <Stage>
component, when selected from the <Navigation>
component.
Since all the reacttraining.com examples are single-page, I'm struggling to determine if I'm making a logic mistake in assuming how my app should be optimally constructed, or a programming error in recreating a relation between the two elements with react-router v4.
Upvotes: 2
Views: 2373
Reputation: 8276
All you need to do is to separate these two div
s as you are wrapping stage
inside the header. And as the Component needs to be rendered in a single element you need another div
around the whole content:
export default class Navigation extends React.Component {
render() {
return (
<Router>
<div>
<div className="navigation">
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
</div>
<div className="stage">
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Switch>
</div>
</div>
</Router>
);
}
}
Update: Updating my answer:
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
const Header = () => <h1>I'm a header</h1>;
const Navigation = () => (
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
);
const Stage = () => (
<div>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</div>
);
const Footer = () => <h6>Footer</h6>;
const Home = () => <h3>Home</h3>;
const About = () => <h3>About</h3>;
const Contact = () => <h3>Contact</h3>;
const App = () => (
<Router>
<div>
<Header />
<Navigation />
<Stage />
<Footer />
</div>
</Router>
);
render(<App />, document.getElementById('root'));
And here is the working version: https://codesandbox.io/s/v21BD37NX
Upvotes: 6