Я пытаюсь создать простое веб-приложение, используя ReactJS, и я хотел использовать Navbar, предоставляемый React-Bootstrap.
Я создал файл Navigation.js, содержащий класс Navigation, чтобы отделить Navbar и маршрутизацию от файла App.js. Однако обе части, похоже, не работают. Когда я загружаю страницу, она просто пуста, навбара нет. Кто-нибудь может заметить ошибку?
Навигация.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;
Я пытался использовать NavItem, уже содержащий LinkContainer из react-router-bootstrap, что привело к тому же результату.
Просто для полноты, 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"/>
);



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Прежде всего, в ваших фрагментах кода не похоже, что вы заключаете свой код в Router, поэтому вы должны убедиться, что вы делаете это внутри App или в ReactDOM.render:
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
rootElement
);
Далее, ваша конкретная проблема заключается в том, что вы визуализируете компонент Nav.Link реакции-загрузки вместо компонента Link реакции-маршрутизатора, поэтому маршрутизатор не улавливает изменения вашего маршрута. К счастью, react-bootstrap предоставляет поддержку рендеринга в большинстве своих компонентов, чтобы указать, какой компонент или элемент вы хотите визуализировать, если вы не хотите использовать значение по умолчанию. Переключитесь на что-то вроде этого:
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>
);
}
}
Похоже, здесь должно быть Nav.Item вместо NavItem
@ kugo2006 Это один и тот же компонент, но да, с Nav.Item на один импорт меньше. Кроме того, вопрос был о Nav.Link и маршрутизаторе, и похоже, что я просто скопировал фрагмент из вопроса ОП и исправил его, поэтому я не делал много рефакторинга :)
Мне интересно, где я могу найти это в документах. Пожалуйста, кто-нибудь вставьте ссылку на документы, где это упоминается для справки. Откуда нам знать, что существует свойство «как»?
@GeorgiGeorgiev реакция-bootstrap.github.io/components/navs/#nav-link-props
я думаю, вы забыли включить bootstrap css, обратитесь к разделу таблиц стилей следующего документа
https://react-bootstrap.github.io/getting-started/introduction/
или просто добавьте следующее в ваш index.html
<link
rel = "stylesheet"
href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
integrity = "sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
crossorigin = "anonymous"
/>
Я уже включил bootstrap css в index.js, в любом случае спасибо за ответ.
здесь нет ничего общего с css, речь идет о реагирующем маршрутизаторе
Для тех, у кого есть проблемы со стилем компонента Link из react-router-dom в панели навигации react-bootstrap, просто добавьте className = "nav-link", например так:
<Link to = "/" className = "nav-link">Home</Link>
вместо
<Nav.Link href = "/">Home</Nav.Link>
У меня тоже была такая же проблема, но я думаю, что вместо этого лучше использовать это: <Nav.Link as = {Link} href = "/">Home</Nav.Link>, где {Link} — компонент из react-router-dom.
@МатиасП. Если вы используете as = {Link}, вы должны заменить href на to
Спасибо. Эти ответы именно то, что я искал <Link to = "/" className = "nav-link">Home</Link> ИЛИ <Nav.Link as = {Link} to = "/" >Home</Nav.Link>
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
и 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>
Это устранило: <Link> за пределами <Router> ошибки для меня.
Обнаружив, что у меня есть проект нетривиального размера, который уже имел jQuery в качестве зависимости, я смог изящно решить несоответствие react-router/react-bootstrap с прослушивателем событий на document.
У этого есть одно преимущество перед другими решениями, заключающееся в том, что оно не требует изменения текущей разметки. Однако может потребоваться написать дополнительную логику, защищающую вызов history.push, в зависимости от потребностей. Также может потребоваться расширить это, чтобы защитить атрибут target, например. target = "_blank".
Если jQuery не нужен, можно написать ванильную реализацию JS с помощью document.addEventListener без особых дополнительных усилий.
// 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>
);
Надеюсь, я не опоздал, чтобы помочь другим людям, пытающимся решить эту проблему.
Вы можете использовать NavLink вместо as = {Link}. Он будет отображаться с тем же поведением, что и Link, но будет «следить» за URL-адресом маршрутизатора, чтобы определить, какая ссылка действительно активна:
<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>
Спасибо, сэр! as = {Link} и to"..." было тем, чего мне не хватало. Странно, что документы начальной загрузки вообще не упоминают об этом.