【问题标题】:ReactJS Bootstrap Navbar and Routing not working togetherReactJS Bootstrap 导航栏和路由不能一起工作
【发布时间】: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-bootstrapLinkContainerNavItem,这导致了相同的结果。

为了完整性,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 reactjs react-router react-bootstrap


    【解决方案1】:

    首先,在您的 sn-ps 中,您似乎没有将代码包装在 Router 中,因此您应该确保在 AppReactDOM.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' 属性?
    【解决方案2】:

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

    &lt;Link to="/" className="nav-link"&gt;Home&lt;/Link&gt;

    而不是

    &lt;Nav.Link href="/"&gt;Home&lt;/Nav.Link&gt;

    【讨论】:

    • 我也遇到了同样的问题,但我认为最好改用这个:&lt;Nav.Link as={Link} href="/"&gt;Home&lt;/Nav.Link&gt; 其中{Link} 是来自react-router-dom 的组件。
    • @MatíasP。如果使用as={Link},则必须将href 替换为to
    • 谢谢。这些答案正是我正在寻找的 &lt;Link to="/" className="nav-link"&gt;Home&lt;/Link&gt;&lt;Nav.Link as={Link} to="/" &gt;Home&lt;/Nav.Link&gt;
    【解决方案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>
      

      这解决了我的&lt;Link&gt; 外部&lt;Router&gt; 错误。

      【讨论】:

        【解决方案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
          猜你喜欢
          • 2023-03-31
          • 2023-01-01
          • 2013-07-28
          • 1970-01-01
          • 2020-08-19
          • 2018-06-18
          • 1970-01-01
          • 2019-07-28
          • 1970-01-01
          相关资源
          最近更新 更多