最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to prevent same component from re-rendering when navigating? React Router v6 - Stack Overflow

programmeradmin7浏览0评论

I'm new to react and I'm having trouble preventing the ponents from re-rendering when I navigate to a different page. Im trying to navigate to my Signup and login page which have nothing but a line of text which is the ONLY thing I want displayed.

The problem is that the Navbar re-renders each time I navigate through the links. I tried different times for react-router v6 but the Navbar is always re-rendering below when I navigate. I simply want the text shown only on the screen but the navbar still shows up

I did not include the Navbar as a Route in my code, but it is being shown every time I navigate to a different link as well as my image slider with react bootstrap carousel.

App.js

import React from 'react';
import Navbar from './Components/Navbar/Navbar';
import ImageSlider from './Components/Slideshow/ImageSlider';
import {BrowserRouter as Router, Route, Routes, Switch} from 'react-router-dom';
import Signup from './Components/Navbar/Signup';
import Login from './Components/Navbar/Login';
import './App.css';

function App() {
  return (
    <div className="App">  
    <Router>
      <Navbar></Navbar>
        <Routes>
          <Route path='/Signup' element={<Signup />}></Route> 
          <Route path='/Login' element={<Login />}></Route>
        </Routes>
      </Router>
      <ImageSlider></ImageSlider>
    </div>
  );
}

export default App;

Navbar.js

import React from 'react';
import { MenuItems } from "./MenuItems";
import {Link,NavLink} from "react-router-dom";


class Navbar extends React.Component {

    render() {
        return(
            <nav className="NavbarItems">
                <ul className={this.state.clicked ? 'nav-menu active' : 'nav-menu'}>
                    {MenuItems.map((item,index) => {
                        return (
                            <li key={index}>
                                 <NavLink to={item.url} activeClassName="is-active" className={item.cName} style={{position: 'relative', right: 0, top: 13}}>
                                     {item.title}
                                 </NavLink>
                            </li>
                        )
                    })}
                </ul>
            </nav>
        )
    }
}

export default Navbar

MenuItems.js

export const MenuItems = [
    {
        title: 'Home',
        url: '/',
        cName: 'nav-links'
    },
    {
        title: 'Sign Up',
        url: '/Signup',
        cName: 'nav-links'
    },
    {
        title: 'Login',
        url: '/Login',
        cName: 'nav-links'
    }
]

ImageSlider.js

import React from 'react';
import "bootstrap/dist/css/bootstrap.css";
import Carousel from 'react-bootstrap/Carousel';

export default function ImageSlider() {
    return (
      <div className='slideshow' style={{ height:120}}>
        <Carousel controls={false}>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src=".jpg"
              alt="Image One"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src=".jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src=".jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src=".jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src=".jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src=".jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src=".jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src=".jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src=".jpg"
              alt="Image Two"
            />
          </Carousel.Item>
        </Carousel>
      </div>
    );
  }

I'm new to react and I'm having trouble preventing the ponents from re-rendering when I navigate to a different page. Im trying to navigate to my Signup and login page which have nothing but a line of text which is the ONLY thing I want displayed.

The problem is that the Navbar re-renders each time I navigate through the links. I tried different times for react-router v6 but the Navbar is always re-rendering below when I navigate. I simply want the text shown only on the screen but the navbar still shows up

I did not include the Navbar as a Route in my code, but it is being shown every time I navigate to a different link as well as my image slider with react bootstrap carousel.

App.js

import React from 'react';
import Navbar from './Components/Navbar/Navbar';
import ImageSlider from './Components/Slideshow/ImageSlider';
import {BrowserRouter as Router, Route, Routes, Switch} from 'react-router-dom';
import Signup from './Components/Navbar/Signup';
import Login from './Components/Navbar/Login';
import './App.css';

function App() {
  return (
    <div className="App">  
    <Router>
      <Navbar></Navbar>
        <Routes>
          <Route path='/Signup' element={<Signup />}></Route> 
          <Route path='/Login' element={<Login />}></Route>
        </Routes>
      </Router>
      <ImageSlider></ImageSlider>
    </div>
  );
}

export default App;

Navbar.js

import React from 'react';
import { MenuItems } from "./MenuItems";
import {Link,NavLink} from "react-router-dom";


class Navbar extends React.Component {

    render() {
        return(
            <nav className="NavbarItems">
                <ul className={this.state.clicked ? 'nav-menu active' : 'nav-menu'}>
                    {MenuItems.map((item,index) => {
                        return (
                            <li key={index}>
                                 <NavLink to={item.url} activeClassName="is-active" className={item.cName} style={{position: 'relative', right: 0, top: 13}}>
                                     {item.title}
                                 </NavLink>
                            </li>
                        )
                    })}
                </ul>
            </nav>
        )
    }
}

export default Navbar

MenuItems.js

export const MenuItems = [
    {
        title: 'Home',
        url: '/',
        cName: 'nav-links'
    },
    {
        title: 'Sign Up',
        url: '/Signup',
        cName: 'nav-links'
    },
    {
        title: 'Login',
        url: '/Login',
        cName: 'nav-links'
    }
]

ImageSlider.js

import React from 'react';
import "bootstrap/dist/css/bootstrap.css";
import Carousel from 'react-bootstrap/Carousel';

export default function ImageSlider() {
    return (
      <div className='slideshow' style={{ height:120}}>
        <Carousel controls={false}>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src="https://cdn.suwalls./wallpapers/nature/beautiful-sunset-in-grand-canyon-47489-1920x1080.jpg"
              alt="Image One"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src="https://wallpaperaccess./full/284466.jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src="https://i.pinimg./originals/09/6a/35/096a35453660aa9b83ba4ab6d9182d61.jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src="https://www.teahub.io/photos/full/2-29537_hd-nature-wallpapers-landscape-green-cute-desktop-waterfall.jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src="https://wallpaperaccess./full/825200.jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src="https://wallpaperaccess./full/825194.jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src="https://hikinglovers.files.wordpress./2014/02/high-mountain-hiking-trail-1920x1080-wallpaper-jjr5fr.jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src="https://wallpaperaccess./full/1859582.jpg"
              alt="Image Two"
            />
          </Carousel.Item>
          <Carousel.Item interval={1500}>
            <img
              className="d-block w-100"
              src="https://cdn.suwalls./wallpapers/nature/mountain-shadowing-upon-the-lake-54621-1920x1200.jpg"
              alt="Image Two"
            />
          </Carousel.Item>
        </Carousel>
      </div>
    );
  }
Share Improve this question asked Jan 23, 2022 at 5:22 ISimpforJesusISimpforJesus 952 silver badges10 bronze badges 1
  • this seems to be react-router-dom v6, is it? – sid Commented Jan 23, 2022 at 6:13
Add a ment  | 

1 Answer 1

Reset to default 5

Starting react-router-dom v6, you can split your ponents and have them rendered only on speicifc routes.

Your App.js should be like

<Router>
    <Routes>
        <Route element={
            <>
                <Navbar />
                <Outlet />
                <ImageSlider />
            </>
        }>
            // routes for authenticated users where navbar & image slider should be displayed 
            <Route path='/home' element={<Home />}> </Route> 
        </Route>

        <Route element={<Outlet />}>
            // routes where navbar & image slider is not rendered
            <Route path='/Signup' element={<Signup />}> </Route> 
            <Route path='/Login' element={<Login />}> </Route>
        </Route>            
    </Routes>
</Router>

By doing this, your /home route will always have Navbar & ImageSlider ponent, where as the guest routes will have only the element that is passed as prop to the route.


As your app grows, I'd suggest to split this into Layouts folder to contain

  1. Auth Layout - a ponent that renders all mon ponents for authenticated users
  2. Guest Layout - a ponent that renders all mon ponents for guest users

so that you can leverage from async code like useEffect or any other hook.

I've drafted a demo to showcase how you can use achieve this by splitting into seperate ponents.

https://codesandbox.io/s/multiple-layouts-react-7r8qu

发布评论

评论列表(0)

  1. 暂无评论