Nav Link not rerendering page when clicked. Force update freezes page - javascript

I have a nav bar for a website I'm building. The links in the nav bar to a section (#id) in the page but do not go to the section and only update the url. If I type in the url in the address bar, it works correctly but when using the link nothing happens.
It only works if I force the page to rerender, but after rerendering the page freezes and I get an error in the console: Uncaught TypeError: Cannot read properties of undefined (reading 'forceUpdate'). I added an onClick and also tried using setState to force re-render.
Index.js
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
App.js
function App() {
return (
<div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/home" element={<Home />} />
</Routes>
</div>
);
}
export default App;
Home.jsx
function Home() {
return (
<div>
<Container fluid>
<NavBar />
<HomeContent />
</Container>
<Pricing />
<Footer />
</div>
);
}
export default Home;
NavBar.jsx
function handleClick() {
this.setState({ state: this.state });
// this.forceUpdate();
}
function NavBar() {
return (
<>
<Navbar variant="dark" expand="lg">
<Container>
<Navbar.Brand onClick={handleClick} as={Link} to="/home">
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="justify-content-end flex-grow-1 pe-3">
<Nav.Link onClick={handleClick} as={Link} to="/home">
Home
</Nav.Link>
<Nav.Link onClick={handleClick} as={Link} to="/home#pricing">
Pricing
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
</>
);
}
export default NavBar;
Pricing.jsx
function Pricing() {
return (
<section id="pricing">
<h2 className="section-heading">This is the pricing section</h2>
</section>
);
}
export default Pricing;
I also tried using withRouter on the NavBar component
I read that if I have to resort to forcing the page to render then I may be doing something wrong but I'm new to React and I've been searching for the past couple of days on better ways to do this but still couldn't find a better way to do it.

this.setState and this.forceUpdate are older React class-based-only component methods. They won't work in React function components.
react-router-dom alone doesn't deal/handle with hash links, i.e. navigating to a specific route path and then scrolling to a specific hash anchor. Currently the react-router-hash-link still works with react-router-dom#6. Import the HashLink from react-router-hash-link and use instead of the Link component from RRD.
Example:
import React from "react";
import { Nav, Navbar } from "react-bootstrap";
import { Link } from "react-router-dom";
import { HashLink } from "react-router-hash-link"; // <-- import hash link
function NavBar() {
return (
<Navbar bg="dark" variant="dark" expand="lg">
<Navbar.Brand as={Link} to="/home"></Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="justify-content-end flex-grow-1 pe-3">
<Nav.Link as={Link} to="/home">
Home
</Nav.Link>
<Nav.Link as={HashLink} to="/home#pricing"> // <-- hash link
Pricing
</Nav.Link>
<Nav.Link as={HashLink} to="/home#about"> // <-- hash link
About
</Nav.Link>
<Nav.Link as={HashLink} to="/home#contact"> // <-- hash link
Contact
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
);
}
export default NavBar;

The best way to solve your problem to create React router structure in your web app. I suggest you to go through React router beginners page.
Also, in your case I suggest to create React router structure such as this structure:
You will have the main index.js file:
const router = createBrowserRouter([
{
path: "/",
element: <Layout />,
children: [
{
path: "mainpage/",
element: <MainPage />,
},
],
},
]);
You will not have app.js file. You will just have a layout.jsx file:
import { Outlet } from 'react-router-dom';
import Nav from "./components/Nav";
const Layout = () => {
return (<>
<Nav />
<Outlet />
</>)
}
And you should just add paths and more children to index js. Just create some components and add them to children array as a main page one.
And in your nav component you must have links to your pages like in the following nav component example:
import React from 'react';
import { Link } from "react-router-dom";
function Nav(props) {
return (
<header className="header">
<div className="header-container">
<nav className="header-nav">
<ul className="nav-list">
<li>
<Link to={`mainpage/`}>Home</Link>
</li>
<li>
<Link to={`News/`}>News</Link>
</li>
<li>
<Link to={`About/`}>About</Link>
</li>
<li>
<Link to={`Contacts`}>Contacts</Link>
</li>
</ul>
</nav>
</div>
</header>
);
}
export default Nav;
I hope you will solve your issue.

Related

Login page and NavBar formatted with Reactstrap (Vertical and with custom background and text color)

I'm trying to make a login page , which would let me access me to the main site with displays a NavBar. I'm using ReactStrap, and I can't find the way of making the NavBar vertical instead of horizontal, neither setting the background and text colours and images. I could achieve to make a conditional rendering (to let administrator users to access some funcionalities like adding products, other users, and make puchrases, while sellers users are only allowed to make sales and view the sales registers).
Here's my code:
App.js:
import React from 'react';
import "./bootstrap.app.css";
import { BrowserRouter as Router, Route} from "react-router-dom";
import Example from "./componentes/navbar.componente"
import RegistroVentas from "./componentes/registro-ventas.componente";
import EditarVenta from "./componentes/editar-venta.componente";
import VenderProducto from "./componentes/realizar-venta.componente";
import NuevoUsuario from "./componentes/nuevo-usuario.componente";
import NuevoProducto from "./componentes/nuevo-producto.componente";
import ComprarProducto from "./componentes/realizar-compra.componente";
function App() {
return (
<Router>
<div className="container">
<Example />
<br/>
<Route path="/" exact component={RegistroVentas} />
<Route path="/registroVentas" component={RegistroVentas} />
<Route path="/editar/:id" component={EditarVenta} />
<Route path="/venta" component={VenderProducto} />
<Route path="/nuevoUsuario" component={NuevoUsuario} />
<Route path="/nuevoProducto" component={NuevoProducto} />
<Route path="/compra" component={ComprarProducto} />
</div>
</Router>
);
}
export default App;
navbar.js:
import React from 'react';
import {
Collapse,
Navbar,
NavbarToggler,
NavbarBrand,
Nav,
Badge,
NavItem,
NavLink,
UncontrolledDropdown,
DropdownToggle,
DropdownMenu,
DropdownItem } from 'reactstrap';
//import FontAwesome from '#fortawesome/react-fontawesome';
//import 'Ventas' from './ventas-cod'
class Ventas extends React.Component {
render() {
return(
<NavItem>
<NavLink href="/venta">
<Badge pill color="dark">Venta</Badge>
</NavLink>
</NavItem>
);
}
}
class Compra extends React.Component {
render() {
return(
<NavItem>
<NavLink href="/compra">
<Badge pill color="dark">Compra</Badge>
</NavLink>
</NavItem>
);
}
}
class Altas extends React.Component {
render () {
return(
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret>
<Badge pill color="dark">Altas</Badge>
</DropdownToggle>
<DropdownMenu right>
<DropdownItem>
<NavLink href="/nuevoUsuario">
<Badge pill color="dark">Usuario</Badge>
</NavLink>
</DropdownItem>
<DropdownItem>
<NavLink href="/nuevoProducto">
<Badge pill color="dark">Producto</Badge>
</NavLink>
</DropdownItem>
<DropdownItem divider />
<DropdownItem>
Reset
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
);
}
}
export default class Example extends React.Component {
constructor(props) {
super(props);
this.tipoUsuario='administrador';
this.toggle = this.toggle.bind(this);
this.state = {
isOpen: false
};
}
toggle() {
this.setState({
isOpen: !this.state.isOpen
});
}
render() {
return (
<div>
<Navbar color="green" expand="lg">
<NavbarBrand href="/">Supermercado Caplan</NavbarBrand>
<NavbarToggler vertical className="d-flex" onClick={this.toggle} />
<Collapse isOpen={this.state.isOpen} navbar>
<Nav className="d-flex ml-auto" >
<Ventas />
{this.tipoUsuario=='administrador' ?
<Compra /> : <a></a>
}
{this.tipoUsuario=='administrador' ?
<Altas /> : <a></a>
}
</Nav>
</Collapse>
</Navbar>
</div>lt
);
}
}
Here's what I'm getting:
Here's something I would like to get:
Does anyone have an idea of what should I do?
Thank's a lot!
In Reactstrap, there's no such a thing like a native component called Sidebar.
However, it's possible to download a template with a sidebar implemented, and then wrap the whole application into it.
For the login cuestion, there's a lot of examples on the web. While all of them should work correctly if implemented properly, I've chosen one of the simplest I found, which works fine for the kind of project I'm doing. However, while it allows me to login with my credentials into a local deployment, it isn't probably the best solution for an application deployed into a web service, since the security of the system it's not just a big deal for an app which is running into a local machine, just written for academic purposes.
So then, here's the template I've found for the Reactstrap sidebar and the login method in which I've based on to implement in my app, and also my app with both things implemented.
Sidebar template:
https://codesandbox.io/s/5ku6t
Login method used:
https://contactmentor.com/login-form-react-js-code/
App with login and sidebar implemented:
https://gitlab.com/leandrocaplan/supermercado-caplan-final-programacion-iii-inspt-utn
(See the frontend folder to see the implementation)
Notice that in my app, the way I've found to format the sidebar, and also the topbar, is creating my own CSS classes, and apply them into the sidebar and topbar components. These classes are found in the App.css file at the correspondent frontend directory.

Bootstrap Navbar does not work in React JS for single page website

I am making a single page website. I added the Bootstrap navbar to Menu.js using React Router but once I add the menu.js to App.js the website becomes blank. Besides the links are not working. They are supposed to jump to the given component on the same page.
Here is my code for App.js
import "./App.css";
import "./components/Introduction";
import Menu from "./components/Menu";
import Introduction from "./components/Introduction";
import Team from "./components/Team";
import Products from "./components/Products";
import Contact from "./components/Contact";
import BackgroundImage from "./components/BackgroundImage";
import "bootstrap/dist/css/bootstrap.min.css";
function App() {
return (
<div className="App">
<Menu />
<BackgroundImage />
<div className="container titel text-center">
<h1>Titel</h1>
<h2>
<em>Subtitle</em>
</h2>
</div>
<Introduction />
<Products />
<Team />
<Contact />
</div>
);
}
export default App;
Here is my code for Menu.js (Navbar)
import React from "react";
import "./Menu.css";
import { Navbar, Nav, Container } from "react-bootstrap";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import Introduction from "./Introduction";
import Team from "./Team";
import Products from "./Products";
import Contact from "./Contact";
import App from "../App";
function Menu() {
return (
<Router>
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand as={Link} to={"/"}>
React-Bootstrap
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Nav.Link as={Link} to={"/introduction"}>
Introduction
</Nav.Link>
<Nav.Link as={Link} to={"/products"}>
Products
</Nav.Link>
<Nav.Link as={Link} to={"/team"}>
Team
</Nav.Link>
<Nav.Link as={Link} to={"/contact"}>
Contact
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
<Routes>
<Route exact path="/">
<App />
</Route>
<Route path="/introduction">
<Introduction />
</Route>
<Route path="/products">
<Products />
</Route>
<Route path="/team">
<Team />
</Route>
<Route path="/contact">
<Contact />
</Route>
</Routes>
</Router>
);
}
export default Menu;
I had to use Routes instead of Switch (error message).
I tried to add the code between Routes to index.js and also to App.js. But none of them worked.
You have put Menu inside of App, and App inside a route of Menu. Yes, this will go wrong (;
I recommend having a layout like this:
export const App = () => {
return (
<BrowserRouter>
// On every page, could be nav
<Router>
<Route></Route>
<Route></Route>
<Route></Route>
<Route></Route>
<Route></Route>
</Router>
// On every page
</BrowserRouter>
);
};
And not have the Router inside of your nav.
In react-router-dom#6 the Route component API changed. Routed components are rendered on a single element prop, not as children components of the Route. You might also want to wrap App with the Router component and render the routes there separately from the navigation component.
Example:
function App() {
return (
<Router>
<div className="App">
<Menu />
<BackgroundImage />
<div className="container titel text-center">
<h1>Titel</h1>
<h2>
<em>Subtitle</em>
</h2>
</div>
<Routes>
<Route path="/" element={<App />} />
<Route path="/introduction" element={<Introduction />} />
<Route path="/products" element={<Products />} />
<Route path="/team" element={<Team />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</div>
</Router>
);
}
...
function Menu() {
return (
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand as={Link} to="/">
React-Bootstrap
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Nav.Link as={Link} to="/introduction">
Introduction
</Nav.Link>
<Nav.Link as={Link} to="/products">
Products
</Nav.Link>
<Nav.Link as={Link} to="/team">
Team
</Nav.Link>
<Nav.Link as={Link} to="/contact">
Contact
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
);
}

how do i do a href in react-bootstrap from the component header to another component in the component App?

What im trying to do is a link between different components in my page, i have a component header with a bunch of links and i want to make reference to anotother component on the same page, in other words im trying to do the following thing but with react:
Hi!
<div id="#move">You have been moved</div>
This is what i have in the header component im using react-bootstrap, i've found some ways to do it without it but i need to do it with it
export default function Header() {
return (
<>
<Navbar variant="dark" expand="lg" style={{ "background-color": "#1A2A4E" }} sticky="top" >
<Navbar.Brand href="#home">Logo</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto" />
<Nav>
<LinkContainer to={{
hash:"Footer"
}}>
<Nav.Link href="#">Actividades</Nav.Link>
</LinkContainer>
<Nav.Link href="#">Fechas</Nav.Link>
<Nav.Link href="#">Cursos</Nav.Link>
<Nav.Link href="#">Instalaciones</Nav.Link>
<Nav.Link href="#">Contacto</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
</>
)
}
and then in the App the first link gets the Actividades but the href doesnt work the App component is:
function App() {
return (
<div className="App">
<div className="imagen-fondo" />
<div className="fondo-blaquesino" />
<div className="">
<Header Footer={<Footer/>} />
<Infoinicio />
</div>
<div className="">
<Actividades />
<Cursos />
<InscrCalendario />
<Instalaciones />
<Contacto />
<div id="#Footer" />
<Footer />
</div>
</div>
);
}
So, you want to auto scroll to the selected id, rite? I achieve it using <NavLink /> from reactstrap. Here is how it works
NavigationBar.tsx
import React, { useState } from 'react';
import { withRouter } from 'react-router-dom';
import {
Navbar, NavbarToggler, Collapse,
Nav, NavItem, NavLink,
} from 'reactstrap';
import { HistoryProps } from '../../interfaces';
import './TopBar.scss';
function NavigationBar(props: HistoryProps) {
const [isOpen, setIsOpen] = useState(false);
const toggleNav = () => setIsOpen(!isOpen);
const path = props.history.location.hash;
return (
<Navbar expand="md" className="navbar-wrapper">
<NavbarToggler
onClick={toggleNav}
data-testid="navbar-toggler"
className="navbar navbar-light outline-none"
/>
<Collapse isOpen={isOpen} navbar data-testid="navbar-collapse" className="h-100">
<Nav className="ml-auto h-100" navbar>
<NavItem className="navbar-navitem pl-2 pr-2" active={!path || path.includes('#about-me')}>
<NavLink className="font-size-12" href="#about-me">
About Me
</NavLink>
</NavItem>
</Nav>
</Collapse>
</Navbar>
);
}
export default withRouter(NavigationBar);
And defined the target component/element, in my case, in another component.
LandingPage.tsx
import React from 'react';
import { Row } from 'reactstrap';
import './LandingPage.scss';
export default function LandingPage() {
return (
<div className="container-fluid">
<Row className="about-me-wrapper id-wrapper" id="about-me">
{/* Element here */}
</Row>
</div>
);
}

react-router-dom doesn't work for my project

I installed react-router-dom to switch between navbar elements. The library does not want to cooperate with my project. After clicking on the navbar element I am not redirected to the required component. Sometimes when I click on a selected item the menu moves slightly to the left. My code looks like this:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
ReactDOM.render(
<App />, document.getElementById('root'));
Navbar.js
import React, { useState } from "react";
import App from '../components/App'
import About from '../components/About';
import Services from '../components/Services';
import Contact from '../components/Contact';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
const Navbar = () => {
const [navLinkOpen, navLinkToggle] = useState(false);
const handleNavLinksToggle = () => {
navLinkToggle(!navLinkOpen);
};
const renderClasses = () => {
let classes = "navlinks";
if(navLinkOpen) {
classes += " ' ' + active";
}
return classes;
};
return (
<nav>
<div className="logo">
<h4>Delightartco</h4>
</div>
<ul className={renderClasses()}>
<Router>
<li className="link"><Link to={"/home"}>Home</Link></li>
<li className="link"><Link to={"/about"}>About</Link></li>
<li className="link"><Link to={"/services"}>Services</Link></li>
<li className="link"><Link to={"/contact"}>Contact</Link></li>
<Switch>
<Route path="/home" component={App}>
</Route>
<Route path="/about" component={About}>
</Route>
<Route path="/services" component={Services}>
</Route>
<Route path="/contact" component={Contact}>
</Route>
</Switch>
</Router>
</ul>
<div onClick={handleNavLinksToggle} className="hamburger-toggle">
<i className="fas fa-bars fa-lg"></i>
</div>
</nav>
)
}
export default Navbar;
App.js
import React from 'react';
import '../../src/App.css';
import Navbar from './Navbar';
import Wrapper from './Wrapper';
import {Content, Winnie, Testimonials, Values, Secrets, Footer} from '../components/Content';
function App() {
return (
<div>
<Navbar />
<Wrapper />
<Content />
<Winnie />
<Testimonials />
<Values />
<Secrets />
<Footer />
</div>
)
}
export default App;
These are few issues in your code:
App is your root React component, and you gave it a route: <Route path="/home" component={App}></Route>. This is causing a recursive / infinite loop. App component inside App component.
Code structure looks complex.
Here is a proposed fixed code:
index.jsx:
ReactDOM.render(<App />, document.getElementById("root"));
App.jsx:
export default function App() {
return (
<StrictMode>
<Routes />
</StrictMode>
);
}
Routes.jsx:
export default function Routes() {
return (
<Router>
{/* Route components would be visible only at their route */}
<Switch>
<Route exact path="/about" component={About}></Route>
<Route exact path="/services" component={Services}></Route>
<Route exact path="/contact" component={Contact}></Route>
</Switch>
{/* Below components would be visible always at UI */}
<Navbar /> {/* Top navigation Link's */}
<Wrapper />
<Content />
<Winnie />
<Testimonials />
<Values />
<Secrets />
<Footer /> {/* Bottom navigation Link's */}
</Router>
);
}
There are several things to keep in mind when using react-router.
The Router or BrowserRouter component should wrap all your routes and your links. Generally, if your app does not need more than one Router, its better to wrap your whole App with the Router.
The Link component's job is to simply navigate to the page and can be used anywhere you want to show a link to someplace e.g. in the Navbar.
The Route (not Router) component's placement is very important. It should be placed where you want to render the content. In your code you are rendering the routes in the Navbar and are unable to see the routes being rendered due to invalid / improper structure.
Navbar.js
Your Navbar should only contain the links while the Router should be on the top-level and the Switch / Routes should be placed where you want to render the content.
function Navbar() {
return (
<nav>
{/* Move `Router` to top-level e.g. in App.js */}
<ul>
<li className="link">
<Link to={"/home"}>Home</Link>
</li>
<li className="link">
<Link to={"/about"}>About</Link>
</li>
<li className="link">
<Link to={"/services"}>Services</Link>
</li>
<li className="link">
<Link to={"/contact"}>Contact</Link>
</li>
</ul>
{/* Move `Switch and Routes` to where you want to render the content e.g. in Content.js */}
</nav>
);
}
App.js
function App() {
return (
<Router>
<div>
<Navbar />
<Wrapper />
<Switch>
<Route path="/home" component={App}></Route>
<Route path="/about" component={About}></Route>
<Route path="/services" component={Services}></Route>
<Route path="/contact" component={Contact}></Route>
</Switch>
<Winnie />
<Testimonials />
<Values />
<Secrets />
<Footer />
</div>
</Router>
);
}

ReactJS Bootstrap Navbar and Routing not working together

I am trying to create a simple Webapp using ReactJS, and I wanted to use the Navbar provided by React-Bootstrap.
I created a Navigation.js file containing a class Navigation to separate the Navbar and the Routing from the App.js file. However, both parts do not seem to work. When I load the page, it is just empty, there is no Navbar. Can anyone spot a mistake?
Navigation.js:
import React, { Component } from 'react';
import { Navbar, Nav, Form, FormControl, Button, NavItem } from 'react-bootstrap';
import { Switch, Route } from 'react-router-dom';
import { Home } from './Page';
class Navigation extends Component {
render() {
return (
<div>
<div>
<Navbar>
<Navbar.Brand href="/">React-Bootstrap</Navbar.Brand>
<Navbar.Collapse>
<Nav className="mr-auto">
<NavItem eventkey={1} href="/">
<Nav.Link href="/">Home</Nav.Link>
</NavItem>
</Nav>
<Form inline>
<FormControl type="text" placeholder="Search" className="mr-sm-2" />
<Button variant="outline-success">Search</Button>
</Form>
</Navbar.Collapse>
</Navbar>
</div>
<div>
<Switch>
<Route exact path='/' component={Home} />
<Route render={function () {
return <p>Not found</p>
}} />
</Switch>
</div>
</div>
);
}
}
export default Navigation;
App.js:
import React, { Component } from 'react';
import Navigation from './components/routing/Navigation';
class App extends Component {
render() {
return (
<div id="App">
<Navigation />
</div>
);
}
}
export default App;
I tried using a NavItem containing a LinkContainer from react-router-bootstrap already, which led to the same result.
Just for completeness, Page.js:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
export const Page = ({ title }) => (
<div className="App">
<div className="App-header">
<h2>{title}</h2>
</div>
<p className="App-intro">
This is the {title} page.
</p>
<p>
<Link to="/">Home</Link>
</p>
<p>
<Link to="/about">About</Link>
</p>
<p>
<Link to="/settings">Settings</Link>
</p>
</div>
);
export const About = (props) => (
<Page title="About"/>
);
export const Settings = (props) => (
<Page title="Settings"/>
);
export const Home = (props) => (
<Page title="Home"/>
);
First of all, in your snippets it doesn't seem like you're wrapping your code in a Router, so you should make sure that you're doing that inside App or in ReactDOM.render:
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
rootElement
);
Next, your specific problem is that you're rendering react-bootstrap's Nav.Link instead of react-router's Link component, so the router is not picking up your route changes. Fortunately, react-bootstrap provides a render prop in most of its components to specify which component or element you want to render if you don't want the default. Switch to something like this:
import { Switch, Route, Link } from 'react-router-dom';
class Navigation extends Component {
render() {
return (
<div>
<div>
<Navbar>
<Navbar.Brand as={Link} to="/" >React-Bootstrap</Navbar.Brand>
<Navbar.Collapse>
<Nav className="mr-auto">
<NavItem eventkey={1} href="/">
<Nav.Link as={Link} to="/" >Home</Nav.Link>
</NavItem>
</Nav>
<Form inline>
<FormControl type="text" placeholder="Search" className="mr-sm-2" />
<Button variant="outline-success">Search</Button>
</Form>
</Navbar.Collapse>
</Navbar>
</div>
<div>
<Switch>
<Route exact path='/' component={Home} />
<Route render={function () {
return <p>Not found</p>
}} />
</Switch>
</div>
</div>
);
}
}
For those who have a problem with styling Link component from react-router-dom in react-bootstrap navbar, simply add className="nav-link", like this:
<Link to="/" className="nav-link">Home</Link>
instead of
<Nav.Link href="/">Home</Nav.Link>
I hope I'm no late to help some other people trying to solve this.
You can use the NavLink, instead of as={Link}. It will render with the same behavior of Link, but will "watch" the router URL to define which link is indeed active:
<Nav defaultActiveKey="/bills" as="ul">
<Nav.Item as="li">
<Nav.Link as={NavLink} to="/bills">Dividas</Nav.Link>
</Nav.Item>
<Nav.Item as="li">
<Nav.Link as={NavLink} to="/other">Em construção</Nav.Link>
</Nav.Item>
</Nav>
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
and Navbar.js:
import React from 'react';
import {Container,Navbar,Nav,NavItem } from 'react-bootstrap';
import {Link} from 'react-router-dom';
<Nav className="ml-auto">
<NavItem> <Link className="nav-link" to="/">Home</Link> </NavItem>
<NavItem> <Link className="nav-link" to="/about">About</Link> </NavItem>
<NavItem> <Link className="nav-link" to="/contact">Contact</Link> </NavItem>
</Nav>
This resolved the: <Link> outside a <Router> error for me.
Having found myself with a project of non-trivial size, and one that already had jQuery as a dependency I was able to gracefully solve the react-router / react-bootstrap mismatch with an event listener on the document.
This has one advantage over other solutions in that it requires no changes to the current markup. However, one may need to write some additional logic guarding the history.push call depending on needs. One may also need to expand this to guard for the target attribute, e.g. target="_blank".
If jQuery is not desired, one may be able to write a vanilla JS implementation with document.addEventListener without much additional effort.
// react-router#5
// usage of history may vary depending on version
import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
// IIFE scoping jQuery for us
(($) => {
// Wait for document ready
$(() => {
$(document).on('click', '[href]', (event) => {
// Only target links targeting our application's origin
if (event.currentTarget.href.indexOf(window.location.origin) === 0) {
// Prevent standard browser navigation
event.preventDefault();
const path = event.currentTarget.href.slice(window.location.origin.length);
history.push(path);
}
});
});
})(jQuery);
const Routing = (props) => (
<Router history={ history }>
...
</Router>
);
Currently, with react v18 and react-router v6.4, the approach is working for me is a bit different.
To make the links properly work with react-route use as={Link} in the Nav.Link item.
And to make the tabs highlight you need to use eventKey as described in the documentation: EventKey is used to determine and control the active state of the parent Nav
Here is an example.
Notice that the changes also affect the Navbar.Brand component.
import { Link, useLocation } from 'react-router-dom';
const AppNavbar = () => {
const location = useLocation();
const activeKey = location.pathname === '/' ? '/projects' : location.pathname;
return (
<Navbar expand="lg" className="theme-navbar">
<Container>
<Navbar.Brand as={Link} to="/">
My Projects
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav activeKey={activeKey} className="me-auto">
<Nav.Link as={Link} eventKey="/projects" to="/projects">
Projects
</Nav.Link>
<Nav.Link as={Link} eventKey="/work" to="/work">
Ongoing Tasks
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
);
};
i think you forgot to include bootstrap css, refer to the stylesheets section of the following doc
https://react-bootstrap.github.io/getting-started/introduction/
or just add the following to ur index.html
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
crossorigin="anonymous"
/>

Categories