ReactJS Bootstrap 导航栏和路由不能一起工作
Posted
技术标签:
【中文标题】ReactJS Bootstrap 导航栏和路由不能一起工作【英文标题】:ReactJS Bootstrap Navbar and Routing not working together 【发布时间】:2019-07-17 12:07:28 【问题描述】:我正在尝试使用 ReactJS 创建一个简单的 Webapp,并且我想使用 React-Bootstrap 提供的 Navbar
。
我创建了一个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;
我尝试使用包含来自react-router-bootstrap
的LinkContainer
的NavItem
,这导致了相同的结果。
为了完整性,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"/>
);
【问题讨论】:
【参考方案1】:首先,在您的 sn-ps 中,您似乎没有将代码包装在 Router
中,因此您应该确保在 App
或 ReactDOM.render
中执行此操作:
import BrowserRouter from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
rootElement
);
接下来,您的具体问题是您正在渲染 react-bootstrap 的 Nav.Link
而不是 react-router 的 Link
组件,因此路由器不会接收您的路由更改。幸运的是,react-bootstrap 在它的大部分组件中都提供了一个 render prop 来指定如果你不想使用默认值,你想要渲染哪个组件或元素。切换到这样的东西:
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>
);
【讨论】:
谢谢先生! as=Link 和 to"..." 是我所缺少的。奇怪的是引导文档根本没有提到这一点。 看起来应该有Nav.Item
而不是NavItem
@kugo2006 它们是相同的组件,但是是的,它与Nav.Item
相比少了一个导入。另外,问题是关于Nav.Link
和路由器的,看起来我只是从 OP 的问题中复制了 sn-p 并修复了它,所以我没有做很多重构:)
我想知道在文档中哪里可以找到它。请有人将链接粘贴到提到的文档中以供参考。我们怎么知道有 'as' 属性?
@GeorgiGeorgiev react-bootstrap.github.io/components/navs/#nav-link-props【参考方案2】:
对于那些在 react-bootstrap 导航栏中对 react-router-dom
中的 Link
组件样式有问题的人,只需添加 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
的组件。
@MatíasP。如果使用as=Link
,则必须将href
替换为to
谢谢。这些答案正是我正在寻找的 <Link to="/" className="nav-link">Home</Link>
或 <Nav.Link as=Link to="/" >Home</Nav.Link>
【参考方案3】:
我希望我能帮助其他试图解决这个问题的人为时不晚。
您可以使用 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>
【讨论】:
【参考方案4】: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>
错误。
【讨论】:
【参考方案5】:发现自己有一个不平凡的项目,并且已经将 jQuery 作为依赖项,我能够优雅地解决 react-router / react-bootstrap 与 document
上的事件侦听器不匹配的问题。
与其他解决方案相比,这具有一个优势,即无需更改当前标记。但是,根据需要,可能需要编写一些额外的逻辑来保护history.push
调用。可能还需要扩展它以保护target
属性,例如target="_blank"
.
如果不需要 jQuery,可以使用document.addEventListener
编写一个普通的 JS 实现,而不需要太多额外的努力。
// 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>
);
【讨论】:
【参考方案6】:我认为您忘记包含引导 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"
/>
【讨论】:
我已经在 index.js 中包含了引导 css,无论如何感谢您的回答。 跟css没什么关系,就是react router以上是关于ReactJS Bootstrap 导航栏和路由不能一起工作的主要内容,如果未能解决你的问题,请参考以下文章
Bootstrap 4 导航栏和内容填充高度 flexbox
导航栏和粘性 Bootstrap 页脚之间的 100% 高度
前端学习(3026):vue+element今日头条管理-让导航栏和路由对应起来