Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React router v4 render component inside element

I'm using the latest version of React Router v4 and I'm trying to render my page components Home/About inside the PageWrap div but the problem I'm having is that if I add the Routes into my header then it will switch the routes but they will display the Home/About component as part of the header and no where I want them to be.

If I put the routes into the PageWrap then the router doesn't work but doesn't throw any errors on the console.

How can I display and switch between components in the PageBody div?

Webpack link

app.js

import React from 'react'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import styled from 'styled-components'
import Header from './Header'

import Home from './pages/Home'
import About from './pages/About'


const Wrapper = styled.div`
  display:flex;
  min-height:100vh;
 flex:1;
 background:#eee;
`
const PageWrap = styled.div`
 margin:0 auto;
 min-width:1400px;
 background: #000;
`

class App extends React.Component { // eslint-disable-line react/prefer-
stateless-function
  render() {
    return (
  <div>
    <Header />
    <Wrapper>
      <PageWrap>
        <Router>
          <Switch>
            <Route exact path="/login" component={Home} />
            <Route exact path="/frontpage" component={About} />
            <Route exact path="/logout" render={() => (<div>logout</div>)} />
          </Switch>
        </Router>
      </PageWrap>
    </Wrapper>
  </div>
)
}
}
export default App

Header.js

import React from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import styled from 'styled-components'
import Home from '../pages/Home'
import About from '../pages/About'
import Topics from '../pages/Topics'

const Wrapper = styled.div`
  width:100%;
  height:100px;
  background:papayawhip;
`

 class Header extends React.Component { // eslint-disable-line react/prefer-
 stateless-function
  render() {
   return (
   <Router>
    <Wrapper>
      <li><Link to="/">Home</Link></li>
      <li><Link to="/about">About</Link></li>
      <li><Link to="/topics">Topics</Link></li>
      <Route exact path="/" component={Home} />
      <Route exact path="/about" component={About} />
      <Route path="/topics" component={Topics} />
    </Wrapper>
  </Router>
  )
  }
}


export default Header

home.js

const Home = () => (<div>Home</div>)

About.js

const About = () => (<div>About</div>)
like image 288
tom harrison Avatar asked Feb 04 '23 14:02

tom harrison


1 Answers

You should only have one <Router> in your application and it should wrap all your <Route /> and <Link/> components in your component tree.

So your render method in App component should be something like this.

render() {
  return (
    <Router>
      <div>
        <Header />
        <Wrapper>
          <PageWrap>
            <Switch>
              <Route exact path="/login" component={Home} />
              <Route exact path="/frontpage" component={About} />
              <Route exact path="/logout" render={() => (<div>logout</div>)} />
            </Switch>
          </PageWrap>
        </Wrapper>
      </div>
    </Router>)
}

And make sure to remove <Router> and all <Route>s from your Header component.

Updated WebpackBin:https://www.webpackbin.com/bins/-KiLrUNoJVxxLhL8UWx1

like image 169
Tharaka Wijebandara Avatar answered Feb 07 '23 11:02

Tharaka Wijebandara