是否可以使用材料-ui按钮导航与react-router?

El.*_*El. 11 reactjs react-router material-ui react-router-dom

我有一个我使用material-UI设计的Web应用程序,我正在使用Button导航来浏览我的基本着陆页组件.

<div className="footer">
  <BottomNavigation value={value} onChange={this.handleChange} className={classes.root}>
    <BottomNavigationAction label="signal" value="signal" icon={<ShowChart />} className={classes.content}/>
    <BottomNavigationAction label="hotlist" value="hotlist" icon={<HotList />} className={classes.content}/>
    <BottomNavigationAction label="analyze" value="analyze" icon={<PieChart />} className={classes.content}/>
    <BottomNavigationAction label="learn" value="learn" icon={<LibraryBooks/>} className={classes.content}/>
    <BottomNavigationAction label="dashboard" value="dashboard" icon={<PermIdentity/>} className={classes.content}/>
  </BottomNavigation>
  </div>
Run Code Online (Sandbox Code Playgroud)

我尝试使用React-Router与这些预先定义的导航组件,但这不起作用,是否有任何可能的方法使用物料UI的按钮导航路由器?material-UI ButtonNavigation API中的按钮导航文章

thi*_*dot 23

是的,这是可能的.你需要使用component道具:

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

import BottomNavigation from '@material-ui/core/BottomNavigation';
import BottomNavigationAction from '@material-ui/core/BottomNavigationAction';

// ....

<BottomNavigation value={value} onChange={this.handleChange}>
    <BottomNavigationAction
        component={Link}
        to="/signal"
        label="signal"
        value="signal"
        icon={<ShowChart />}
        className={classes.content}
    />
</BottomNavigation>
Run Code Online (Sandbox Code Playgroud)

(to支柱用于React Router的Link组件)

这适用于继承自的任何Material-UI组件ButtonBase.

https://material-ui.com/api/bottom-navigation-action/

遗产

ButtonBase组件的属性也可用.您可以利用此行为来定位嵌套组件.

https://material-ui.com/api/button-base/

道具

component - 用于根节点的组件.要么是使用DOM元素的字符串,要么是组件.

  • 如果您需要在访问 url 时将 BottomNavigationAction 显示为已选择,则需要 1. 使用 `react-router-dom` 中的 `useLocation` 获取当前位置 2. 将其提供给 `BottomNavigation` 并使用 `value={location. 3. 为每个 `BottomNavigationAction` 提供适当的 `value` 属性,例如 `value="/about" (4认同)

Dar*_*ll 5

只是为了补充@thirtydot 的精彩答案,以防用户输入搜索并直接访问特定网页(默认情况除外),例如“www.yoursite.com/tab2”,而不是单击第二个按钮,这可能会导致显示的站点与聚焦的底部导航按钮(通常是第一个按钮)之间不匹配。

这是我所做的:
我曾经window.location.pathname直接获取当前路径,即“/tab2”。
这是我的特定用例的代码....

function BottomNavBar(){
    const pathname = window.location.pathname; // in case user visits the path directly. The BottomNavBar is able to follow suit.
    const [value, setValue] = React.useState(pathname);
    const handleChange = (event, newValue) => {
      setValue(newValue);
    };

    return (
        <BottomNavigation value={value} onChange={handleChange} showLabels={true} >
          <BottomNavigationAction label="home" value="/" icon={<HomeIcon />} component={Link} to='/'/>
          <BottomNavigationAction label="resources" value="/resources" icon={<ResourcesIcon /> } component={Link} to='/resources'/>                
          <BottomNavigationAction label="Q&A" value="/qna" icon={<QnAIcon />}  component={Link} to='/qna'/>
          <BottomNavigationAction label="profile" value="/profile" icon={<ProfileIcon />} component={Link} to='/profile'/>
        </BottomNavigation>
      );
}

Run Code Online (Sandbox Code Playgroud)


Jan*_*Jan 5

2023年完整答案

基于@thirdydot 的回答和@trashgenerator 的评论,填补了所有剩余的空白。

如果您想连接BottomNavigationreact-router-dom那么您希望路由器保存单点事实。这意味着依赖useLocation而不是useState存储应用程序状态的这方面并Link更改状态。

有 3 个步骤:

  1. 确保您位于路由器上下文中才能useLocation工作(见下文)。
  2. BottomNavigation集合中value={useLocation().pathname}代替useStateonChange
  3. BottomNavigationAction使用中并将component={Link}to="/signal"设置value为相同的路径。

src/components/RouterBottomNavigation.js

import { useLocation, Link } from 'react-router-dom';
import { BottomNavigation, BottomNavigationAction } from '@mui/material';
/* import icons */

export default function RouterBottomNavigation() {
  return (
    <BottomNavigation
      value={useLocation().pathname}
      className={classes.root}
    >
      <BottomNavigationAction
        component={Link}
        to="/signal"
        value="/signal"
        label="Signal"
        icon={<ShowChart />}
        className={classes.content}
      />
      <BottomNavigationAction
        component={Link}
        to="/dashboard"
        value="/dashboard"
        label="Dashboard"
        icon={<PermIdentity />}
        className={classes.content}
      />
    </BottomNavigation>
  )
}
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?位置路径名现在保存底部导航的状态。

如果是,/dashboard那么您的仪表板BottomNavigationAction处于活动状态,因为它的值也是/dashboard

当您单击BottomNavigationAction同时也是路由器的a 时Link,您可以将位置路径名更改为该to值。

在路由器 comntext 内部

要位于路由器上下文内部,您可以将其放置RouterBottomNavigationOutlet. 例如:

src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import Root from "./routes/root";
import Dashboard from "./routes/dashboard";
import Signal from "./routes/signal";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        path: "dashboard",
        element: <Dashboard />,
      },
      {
        path: "signal",
        element: <Signal />,
      },
    ]
  },
]);

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);
Run Code Online (Sandbox Code Playgroud)

src/routes/root.js

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

import RouterBottomNavigation from "../components/RouterBottomNavigation";

export default function Root() {
  return (
    <>
      <Outlet />
      <RouterBottomNavigation />
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)