soups
soups

Reputation: 53

React router - <Route /> does not render when <Link> not in same component

im trying to format my HTML like so within the body tag:

<header id="header"></header>

<main id="app"></main>

<footer id="footer"></footer>

reason why is so that i have my navigation out of <main></main> and in <header></header>

Im also rendering the corresponding React component individually i.e: document.getElementById("header"), document.getElementById("app") ...:

ReactDOM.render(
  <Header />,
  document.getElementById("header")
);

When clicking <Link to="/log-in"></Link> in <Header /> it breaks out of SPA and jumps to /log-in page.

What am i missing here?

Upvotes: 0

Views: 420

Answers (1)

Predrag Beocanin
Predrag Beocanin

Reputation: 1400

Using ReactDOM.render multiple times will create separate instances unaware of each other source.

Let's go on about restructuring that a bit to make your app feel better:

App.js

import React from 'react';
import { Main } from './components';
const App = () => (
    <Main />
)

ReactDOM.render(<App />, document.getElementById("app"));

Main.js

import React from 'react';
import { Router, Route } from 'react-router-dom';
import { Header, Login, Register, Home } from './components'

const Main = () => (
 <Router>
    <React.Fragment>
      <Header />

      <Route exact path="/" component={Home} />
      <Route path="/login" component={Login} />
      <Route path="/register" component={Register} />

      <Footer />
    </React.Fragment>
  </Router>
)

export { Main };

So this way, we're ever only really rendering one instance. Your header/footer would be placed outside of the router, so whenever the route changes, they remain unaffected. Keep in mind that this will present a challenge, eg if you want your Header to highlight which route is active, the simples way, since it's outside of router and doesn't receive props from it, is to check the url. Also note that we're using <React.Fragment> here, but you're free to use a <div> or anything else you like. Router expect one child only, so if you don't want additional html elements, you can use a fragment!

Upvotes: 5

Related Questions