Darth Plagueris
Darth Plagueris

Reputation: 339

React Router Still Renders Previous Page after Routing to New Component

I am making a landing page for my site, which will have 3 components - header, main and footer, only for the landing page. The header component is just a nav bar with a logo on the left and sign in button on the right.

When the sign in button is clicked, I render a login route using the router but the problem is the previous components of Landing page (Header, Main and Landing) are also rendered with the new routed Login component.

Here's my App.js file where Landing is inserted.

import React, {Component} from 'react';

import Landing from './components/Landing/Landing';

class App extends Component {
    render() {
        return (
            <div className="App">
                <Landing/>
            </div>
        );
    }
}

export default App;

and in Landing component I have this setup:

import React, {Component} from 'react';

import Header from './Header';
import Main from './Main';
import Footer from './Footer'

class Landing extends Component {
    render() {

        return (
            <div className="container__landing">
                <Header/>
                <Main/>
                <Footer/>
            </div>
        );
    }
}

export default Landing;

Here's my header component, for brevity I have left out the other two components:

import React, {Component} from 'react';
import {BrowserRouter as Router, Link} from 'react-router-dom';
import {Route, Switch} from 'react-router';
import Login from '../auth/Login';

class Header extends Component {
    render() {
        return (
            <Router>
                <header className="header">
                    <div className="header__nav">
                        <p>STRONG LIVE</p>
                        <button className="sign_in">
                            <Link to="/login">
                                Sign In
                            </Link>
                        </button>
                    </div>
                    <Route exact path="/login" component={Login}/>
                </header>
            </Router>
        )
    }
}
export default Header;

The login component is rendered but it's placed inside the landing component along with the header and other present components.

I want the login page to be stand-alone and without the header, which is currently above it. I have seen some tutorial where they have used the props.history.push('/path) but in React Dev Tools, none of my components have these props. How do I switch components on button click? Thank you.

Upvotes: 5

Views: 5609

Answers (1)

Arthur Chaloin
Arthur Chaloin

Reputation: 620

When the URL will match the path property of your <Route> component, a.k.a. when you'll be on the /login page, React router will render your <Login> component at the place in your component tree where the corresponding <Route> is.

The problem is that your <Router>, and more specifically your login <Route> are inside the <Landing> component.

If you want the login page to be rendered without header, you should place both the <Landing> and <Login> components inside a <Route>, next to each other. Then, render them conditionally using React Router's <Switch>component :

A <Switch> will iterate over all of its children elements and only render the first one that matches the current location. (see the documentation for details)

Here's an (untested) example :

class App extends Component {
    render() {
        return (
            <div className="App">
                <Router>
                    <Switch>
                        {/* Render the login component alone if we're on /login */}
                        <Route exact path="/login" component={Login} />

                        {/* Otherwise, render the Landing component */}
                        <Route component={Landing} />
                    </Switch>
                </Router>
            </div>
        );
    }
}

Upvotes: 7

Related Questions