【问题标题】:Fetch Param from Route in Nav Bar, React-Router从导航栏中的路由获取参数,React-Router
【发布时间】:2020-09-11 14:03:02
【问题描述】:

我在我的 App.js 中设置了一个路由器,如下所示:

import React from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';
import NavBar from './nav-bar';
import Landing from './landing-page';
import Dashboard from './dashboard';
import Analysis from './analysis';
import '../style.scss';

const App = (props) => {
  return (
    <Router>
      <NavBar />
      <Switch>
        <Route exact path="/" component={Landing} />
        <Route path="/dashboard/:prodID/search" component={Dashboard} />
        <Redirect from="/dashboard/:prodID" to="/dashboard/:prodID/search" />
        <Route path="/dashboard/:prodID/analyze" component={Analysis} />
        <Route component={() => (
          <div id="error">
            <h1>404 ERROR</h1>
            <h2>Page not found</h2>
          </div>
        )}
        />
      </Switch>
    </Router>
  );
};

export default App;

而我的NavBar组件设置如下:

import React, { Component } from 'react';
import { NavLink, withRouter } from 'react-router-dom';
import { Navbar, Nav } from 'react-bootstrap';
import '../style.scss';

class NavBar extends Component {
  constructor(props) {
    super(props);

    this.state = {};
  }

  render() {
    return (
      <Navbar id="nav-bar" bg="dark" variant="dark">
        <Navbar.Brand href="/">
          My Project
        </Navbar.Brand>
        <Navbar.Collapse id="responsive-navbar-nav" className="justify-content-end">
          <Nav>
            <NavLink to="/dashboard/:prodID/search">Search</NavLink>
            <NavLink to="/dashboard/:prodID/analyze">Analyze</NavLink>
          </Nav>
        </Navbar.Collapse>
      </Navbar>
    );
  }
}

export default withRouter(NavBar);

我有两件事想弄清楚:

  1. 我希望能够访问我的 NavBar 组件中的 prodID 路由参数,这样当用户单击路由时,它将采用有效的 prodID 并正确呈现路由。
  2. 如果用户在具有prodID 参数的路线上,我只想在NavBar 中显示NavLinks。例如,如果他们在主路由/ 上,则不会显示链接。但如果他们在/dashboard/[valid prodID]/search 的路线上,链接就会显示出来。

我该如何实施呢?我看过其他关于 SO 处理路由参数和导航栏的帖子,但没有一个回答我的问题。任何帮助表示赞赏。

【问题讨论】:

    标签: javascript reactjs routes react-router


    【解决方案1】:

    我相信您必须将导航栏移到每条路线下方,以便在路径更改时重新渲染并获取正确的参数。

    为了实现它,您可以创建 Layout 组件,该组件将包装您传递的组件并为其添加导航栏:

    // Layout.jsx
    import React from "react";
    import NavBar from './nav-bar';
    
    export const Layout = () => {
      return (
        <div>
          <Navbar />
          <div>{children}</div>
        </div>
      );
    };
    

    然后在您的应用程序中,您可以使用 Layout 组件将每个组件包装在路由中,就像这样

    // App.jsx    
    import React from "react";
    import {
      BrowserRouter as Router,
      Route,
      Switch,
      Redirect
    } from "react-router-dom";
    import NavBar from "./nav-bar";
    import Landing from "./landing-page";
    import Dashboard from "./dashboard";
    import Analysis from "./analysis";
    import { Layout } from "./Layout";
    import "../style.scss";
    
    const App = props => {
      return (
        <Router>
          <Switch>
            <Route exact path="/">
              <Layout>
                <Landing />
              </Layout>
            </Route>
            <Route path="/dashboard/:prodID/search">
              <Layout>
                <Dashboard />
              </Layout>
            </Route>
            <Redirect from="/dashboard/:prodID" to="/dashboard/:prodID/search" />
            <Route path="/dashboard/:prodID/analyze">
              <Layout>
                <Analysis />
              </Layout>
            </Route>
            <Route
              component={() => (
                <div id="error">
                  <h1>404 ERROR</h1>
                  <h2>Page not found</h2>
                </div>
              )}
            />
          </Switch>
        </Router>
      );
    };
    
    export default App;
    

    这种方法将帮助您实现第二个目标。由于导航栏现在嵌套在每个路由下,您可以轻松地从路径中获取参数并有条件地渲染链接,如下所示:

    // NavBar.jsx
    import React from "react";
    import { NavLink, useParams } from "react-router-dom";
    import { Navbar, Nav } from "react-bootstrap";
    import "../style.scss";
    
    const NavBar = () => {
      const { prodID } = useParams();
    
      return (
        <Navbar id="nav-bar" bg="dark" variant="dark">
          <Navbar.Brand href="/">My Project</Navbar.Brand>
          <Navbar.Collapse
            id="responsive-navbar-nav"
            className="justify-content-end"
          >
            <Nav>
              {prodID && (
                <NavLink to={`/dashboard/:${prodID}/search`}>Search</NavLink>
              )}
              {prodID && (
                <NavLink to={`/dashboard/:${prodID}/analyze`}>Analyze</NavLink>
              )}
            </Nav>
          </Navbar.Collapse>
        </Navbar>
      );
    };
    
    export default NavBar;
    

    我尚未对其进行测试,但它应该可以帮助您解决问题。

    【讨论】:

    • useParams 挂钩仅适用于 Route。它在 NavBar 组件之外的任何 Route 组件中不起作用
    • Navbar 位于Layout 组件中,它封装了每个路由内的每个组件。 App 组件中有一个NavBar 实例,这是一个错误。现在已删除。
    • 感谢您提出这个绝妙的主意!
    猜你喜欢
    • 2017-03-10
    • 1970-01-01
    • 2022-01-02
    • 2020-09-23
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 2023-03-12
    • 2016-12-23
    相关资源
    最近更新 更多