Estoy tratando de crear una aplicación web simple usando ReactJS, y quería usar el Navbar
proporcionado por React-Bootstrap.
creé un Navigation.js
archivo que contiene una clase Navigation
para separar el Navbar
y el enrutamiento desde el App.js
archivo. Sin embargo, ambas partes no parecen funcionar. Cuando cargo la página, está vacía, no hay barra de navegación. ¿Alguien puede detectar un error?
Navegación.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="https://stackoverflow.com/">React-Bootstrap</Navbar.Brand>
<Navbar.Collapse>
<Nav className="mr-auto">
<NavItem eventkey={1} href="https://stackoverflow.com/">
<Nav.Link href="https://stackoverflow.com/">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="https://stackoverflow.com/" component={Home} />
<Route render={function () {
return <p>Not found</p>
}} />
</Switch>
</div>
</div>
);
}
}
export default Navigation;
Aplicación.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;
Intenté usar un NavItem
que contiene un LinkContainer
de react-router-bootstrap
ya, lo que condujo al mismo resultado.
Solo para completar, 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="https://stackoverflow.com/">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"/>
);
En primer lugar, en sus fragmentos no parece que esté envolviendo su código en un Router
por lo que debes asegurarte de hacerlo por dentro App
o en ReactDOM.render
:
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
rootElement
);
A continuación, su problema específico es que está procesando react-bootstrap Nav.Link
en lugar de reaccionar-enrutador Link
componente, por lo que el enrutador no detecta los cambios de ruta. Afortunadamente, react-bootstrap proporciona un accesorio de representación en la mayoría de sus componentes para especificar qué componente o elemento desea representar si no desea el valor predeterminado. Cambia a algo como esto:
import { Switch, Route, Link } from 'react-router-dom';
class Navigation extends Component {
render() {
return (
<div>
<div>
<Navbar>
<Navbar.Brand as={Link} to="https://stackoverflow.com/" >React-Bootstrap</Navbar.Brand>
<Navbar.Collapse>
<Nav className="mr-auto">
<NavItem eventkey={1} href="https://stackoverflow.com/">
<Nav.Link as={Link} to="https://stackoverflow.com/" >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="https://stackoverflow.com/" component={Home} />
<Route render={function () {
return <p>Not found</p>
}} />
</Switch>
</div>
</div>
);
}
}
-
¡Gracias Señor! el as={Link} y to”…” era lo que me faltaba. Es extraño que los documentos de arranque no mencionen esto en absoluto.
– mBrice1024
9 de mayo de 2020 a las 3:41
-
Parece que esto debería haber
Nav.Item
en lugar deNavItem
– kugo2006
20 de octubre de 2020 a las 6:22
-
@kugo2006 Son el mismo componente, pero sí, es una importación menos con
Nav.Item
. Además, la pregunta era sobreNav.Link
y el enrutador, y parece que acabo de copiar el fragmento de la pregunta de OP y lo arreglé, así que no hice mucha refactorización 🙂– Sr. Thompson
20 oct 2020 a las 22:50
-
Me pregunto dónde puedo encontrar eso en los documentos. Por favor, alguien pegue el enlace a los documentos donde se menciona como referencia. ¿Cómo debemos saber que existe la propiedad ‘como’?
– Georgi Georgiev
30 de enero de 2021 a las 13:21
-
@GeorgiGeorgiev reaccionar-bootstrap.github.io/components/navs/#nav-link-props
– Sr. Thompson
1 de febrero de 2021 a las 13:27
DedaDev
Para aquellos que tienen un problema con el estilo. Link
componente de react-router-dom
en la barra de navegación react-bootstrap, simplemente agregue className="nav-link"
como esto:
<Link to="/" className="nav-link">Home</Link>
en lugar de
<Nav.Link href="/">Home</Nav.Link>
-
Yo también tuve el mismo problema, pero creo que es mejor usar esto en su lugar:
<Nav.Link as={Link} href="/">Home</Nav.Link>
dónde{Link}
es el componente dereact-router-dom
.– Matías Pizarro
5 oct 2019 a las 21:06
-
@MatíasP. si usa
as={Link}
tienes que reemplazarhref
conto
– Máx.
13 de enero de 2020 a las 6:24
-
Gracias. Estas respuestas son exactamente lo que estaba buscando.
<Link to="/" className="nav-link">Home</Link>
O<Nav.Link as={Link} to="/" >Home</Nav.Link>
– K. Shaikh
27 de junio de 2021 a las 12:35
Espero no llegar tarde para ayudar a otras personas que intentan resolver esto.
Puede utilizar NavLink, en lugar de as={Link}. Se renderizará con el mismo comportamiento de Enlace, pero “observará” la URL del enrutador para definir qué enlace está realmente activo:
<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>
-
Esto no funciona: el tipo ‘”{Link}”‘ no se puede asignar al tipo ‘ElementType
| indefinido’. ¿Querías decir ‘”enlace”‘? -Richard Barraclough
15 de abril a las 7:34
Preeti Maurya
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
y 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="https://stackoverflow.com/">Home</Link> </NavItem>
<NavItem> <Link className="nav-link" to="/about">About</Link> </NavItem>
<NavItem> <Link className="nav-link" to="/contact">Contact</Link> </NavItem>
</Nav>
Esto resolvió: <Link>
fuera de un <Router>
error para mi
Actualmente, con react v18 y react-router v6.4, el enfoque que funciona para mí es un poco diferente.
Para hacer que los enlaces funcionen correctamente con el uso de la ruta de reacción as={Link}
en el Nav.Link
artículo.
Y para resaltar las pestañas, debe usar clave de evento como se describe en la documentación: EventKey se utiliza para determinar y controlar el estado activo del Nav principal
Aquí hay un ejemplo.
Observe que los cambios también afectan a la Navbar.Brand
componente.
import { Link, useLocation } from 'react-router-dom';
const AppNavbar = () => {
const location = useLocation();
const activeKey = location.pathname === "https://stackoverflow.com/" ? '/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>
);
};
-
¡Perfecto! Gracias. Estas api cambian tan rápido que todo lo demás está desactualizado.
– Árboles4elBosque
25 de noviembre de 2022 a las 22:23
-
El tipo ‘”{Link}”‘ no se puede asignar al tipo ‘ElementType
| indefinido’. ¿Querías decir ‘”enlace”‘? -Richard Barraclough
15 abr a las 7:31
Habiéndome encontrado con un proyecto de tamaño no trivial, y uno que ya tenía jQuery como una dependencia, pude resolver con gracia el desajuste de react-router / react-bootstrap con un detector de eventos en el document
.
Esto tiene una ventaja sobre otras soluciones, ya que no requiere cambios en el marcado actual. Sin embargo, es posible que sea necesario escribir alguna lógica adicional que proteja el history.push
llamar según necesidades. También es posible que sea necesario ampliar esto para proteger el target
atributo, por ejemplo target="_blank"
.
Si no se desea jQuery, se puede escribir una implementación JS estándar con document.addEventListener
sin mucho esfuerzo adicional.
// 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>
);
-
¡Perfecto! Gracias. Estas api cambian tan rápido que todo lo demás está desactualizado.
– Árboles4elBosque
25 de noviembre de 2022 a las 22:23
-
El tipo ‘”{Link}”‘ no se puede asignar al tipo ‘ElementType
| indefinido’. ¿Querías decir ‘”enlace”‘? -Richard Barraclough
15 abr a las 7:31
ravibagul91
creo que olvidó incluir bootstrap css, consulte la sección de hojas de estilo del siguiente documento
https://react-bootstrap.github.io/getting-started/introduction/
o simplemente agregue lo siguiente a su index.html
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
crossorigin="anonymous"
/>
-
Ya incluí bootstrap css en index.js, gracias por la respuesta de todos modos.
– No es un nombre
27 de febrero de 2019 a las 20:03
-
no hay nada que ver con css, se trata de reaccionar enrutador
– Doblador
28 de febrero de 2019 a las 7:38