ReactJS Bootstrap Navbar 和 Routing 不能一起工作

IT技术 javascript reactjs react-router react-bootstrap
2021-03-17 15:40:08

我正在尝试使用 ReactJS 创建一个简单的 Web 应用程序,并且我想使用NavbarReact-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;

应用程序.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包含LinkContainerreact-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"/>
);
6个回答

首先,在您的代码段中,您似乎没有将代码包装在 a 中Router,因此您应该确保在内部App或在 中执行此操作ReactDOM.render

import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>, 
  rootElement
  );

接下来,您的具体问题是您正在渲染 react-bootstrapNav.Link而不是 react-router 的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
2021-04-27 15:40:08
谢谢你,先生!as={Link} 和 to"..." 是我所缺少的。奇怪的是,引导程序文档根本没有提到这一点。
2021-05-05 15:40:08
2021-05-08 15:40:08
@kugo2006 它们是相同的组件,但是是的,使用Nav.Item. 另外,问题是关于Nav.Link路由器,看起来我只是从 OP 的问题中复制了片段并修复了它,所以我没有做很多重构:)
2021-05-17 15:40:08
我想知道在哪里可以在文档中找到它。请有人粘贴指向文档的链接以供参考。我们怎么知道有“as”属性?
2021-05-18 15:40:08

对于那些在 react-bootstrap 导航栏中对样式Link组件有问题的人react-router-dom,只需添加className="nav-link",如下所示:

<Link to="/" className="nav-link">Home</Link>

代替

<Nav.Link href="/">Home</Nav.Link>

@MatíasP。如果使用as={Link}你必须替换hrefto
2021-04-27 15:40:08
我有同样的问题,但我却认为这是更好地使用它代替: <Nav.Link as={Link} href="/">Home</Nav.Link>其中,{Link}是从组件react-router-dom
2021-05-08 15:40:08
谢谢。这些答案正是我正在寻找的<Link to="/" className="nav-link">Home</Link><Nav.Link as={Link} to="/" >Home</Nav.Link>
2021-05-12 15:40:08

我希望我不会迟到帮助其他一些试图解决这个问题的人。

您可以使用 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>
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>
);