React Material UI BottomNavigation 组件路由问题
Posted
技术标签:
【中文标题】React Material UI BottomNavigation 组件路由问题【英文标题】:React Material UI BottomNavigation component Routing Issue 【发布时间】:2018-07-04 18:07:25 【问题描述】:我正在尝试从 Material UI 实现底部导航组件,但我在用户使用浏览器的后退和前进按钮时遇到了问题。
问题是,BottomNavigation 组件被配置为在按下导航项按钮时更改布局中的页面。然而,当浏览器用于返回上一页时,它不会更改 BottomNavigation 项的选定索引。
我留下的是一个不一致的状态。
使用浏览器按钮时如何更改导航组件的选定索引?
这是 UI 的外观:-
[
这是根组件:-
import React from 'react'
import browserHistory, withRouter from 'react-router';
import PropTypes from 'prop-types'
import connect from 'react-redux'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import AppBar from 'material-ui/AppBar'
import Paper from 'material-ui/Paper'
import MyBottomNavigation from '../material-ui/MyBottomNavigation'
const style =
padding: 10,
height: '85vh'
class Root extends React.Component
constructor(props)
super(props)
this.state =
bottomNavItemIndex : 0
render()
return (
<MuiThemeProvider>
<div>
<AppBar title="Pluralsight Admin"
iconClassNameRight="muidocs-icon-navigation-expand-more"
showMenuIconButton=false
zDepth=1
/>
<Paper zDepth=1 style=style>
this.props.children
</Paper>
<MyBottomNavigation/>
</div>
</MuiThemeProvider>
)
Root.propTypes =
children: PropTypes.object.isRequired
export default Root
这是导航组件:-
class MyBottomNavigation extends Component
constructor(props)
super(props)
this.state =
selectedIndex: 0
this.selectBottomNavigationItem = this.selectBottomNavigationItem.bind(this)
selectBottomNavigationItem(index)
this.setState(selectedIndex: index)
switch(index)
case 0:
return browserHistory.push('/')
case 1:
return browserHistory.push('/courses')
case 2:
return browserHistory.push('/authors')
default:
return browserHistory.push('/')
render()
return (
<Paper zDepth=1>
<BottomNavigation selectedIndex=this.state.selectedIndex>
<BottomNavigationItem
label="Home"
icon=recentsIcon
onClick=() => this.selectBottomNavigationItem(0)
/>
<BottomNavigationItem
label="Course"
icon=favoritesIcon
onClick=() => this.selectBottomNavigationItem(1)
/>
<BottomNavigationItem
label="Authors"
icon=nearbyIcon
onClick=() => this.selectBottomNavigationItem(2)
/>
</BottomNavigation>
</Paper>
)
export default MyBottomNavigation
【问题讨论】:
我的情况完全相同。如果我找到解决方案,我会发布答案。 【参考方案1】:刚刚实现了一个工作!
诀窍是制作一个新的导航栏组件,该组件包装 Material UI BottomNavigation
并使用 react-router-dom
的 withRouter
高阶函数将其导出。然后你可以对传入 props 的当前路由进行一些摆弄,并根据路由数组(哪个路由对应哪个值)设置BottomNavigation
组件的值。
我的代码与您最初发布的代码有些不同,我只是从BottomNavigation
示例here 和react-router-dom
here 的使用示例中脱离出来。
这是我的实现:
/src/App.jsimport React, Component from 'react';
import './App.css';
import BrowserRouter as Router, Route from 'react-router-dom';
import PrimaryNav from './components/PrimaryNav';
// Views
import HomeView from './views/HomeView';
class App extends Component
render()
return (
<Router>
<div className="app">
<Route path="/" component=HomeView />
<PrimaryNav />
</div>
</Router>
);
export default App;
/src/components/PrimaryNav.js
import React, Component from 'react';
import Link, withRouter from 'react-router-dom';
import BottomNavigation from '@material-ui/core/BottomNavigation';
import BottomNavigationAction from '@material-ui/core/BottomNavigationAction';
import LanguageIcon from '@material-ui/icons/Language';
import GroupIcon from '@material-ui/icons/Group';
import ShoppingBasketIcon from '@material-ui/icons/ShoppingBasket';
import HelpIcon from '@material-ui/icons/Help';
import EmailIcon from '@material-ui/icons/Email';
import './PrimaryNav.css';
class PrimaryNav extends Component
state =
value: 0,
pathMap: [
'/panoramas',
'/members',
'/shop',
'/about',
'/subscribe'
]
;
componentWillReceiveProps(newProps)
const pathname = newProps.location;
const pathMap = this.state;
const value = pathMap.indexOf(pathname);
if (value > -1)
this.setState(
value
);
handleChange = (event, value) =>
this.setState( value );
;
render()
const value, pathMap = this.state;
return (
<BottomNavigation
value=value
onChange=this.handleChange
showLabels
className="nav primary"
>
<BottomNavigationAction label="Panoramas" icon=<LanguageIcon /> component=Link to=pathMap[0] />
<BottomNavigationAction label="Members" icon=<GroupIcon /> component=Link to=pathMap[1] />
<BottomNavigationAction label="Shop" icon=<ShoppingBasketIcon /> component=Link to=pathMap[2] />
<BottomNavigationAction label="About" icon=<HelpIcon /> component=Link to=pathMap[3] />
<BottomNavigationAction label="Subscribe" icon=<EmailIcon /> component=Link to=pathMap[4] />
</BottomNavigation>
);
export default withRouter(PrimaryNav);
这是我的版本号:
"@material-ui/core": "^1.3.1",
"@material-ui/icons": "^1.1.0",
"react": "^16.4.1",
"react-dom": "^16.4.1",
【讨论】:
【参考方案2】:刚刚为这个here找到了一个非常巧妙的解决方案:
基本上你只需在每次渲染时创建一个pathname
常量,使用window.location.pathname
并确保每个<BottomNavigationAction />
的值属性设置为与路由相同(包括前面的正斜杠)......类似:
const pathname = window.location.pathname
const [value, setValue] = useState(pathname)
const onChange = (event, newValue) =>
setValue(newValue);
return (
<BottomNavigation className=classes.navbar value=value onChange=onChange>
<BottomNavigationAction component=Link to='/' value='/' label='Home' icon=<Home/> />
<BottomNavigationAction component=Link to='/another-route' value='/another-route' label='Favourites' icon=<Favorite/> />
</BottomNavigation>
)
这意味着value
的初始状态始终取自当前 URL。
【讨论】:
【参考方案3】:我认为您应该避免对该组件进行内部状态管理。如果您需要知道并突出显示当前选定的路线,您可以只使用 react-router-dom 中的 NavigationLink 而不是 Link。一个“活动”类将被添加到相应的元素中。如果您希望导航元素仅在检测到完全匹配时处于活动状态,您只需要注意确切的道具。
[更新] 我写了错误的组件名称,即 NavLink,而不是 NavigationLink。我的错。这是文档的链接https://reactrouter.com/web/api/NavLink
【讨论】:
react-router-dom
没有NavigationLink
组件。
对不起,我是说 NavLink reactrouter.com/web/api/NavLink以上是关于React Material UI BottomNavigation 组件路由问题的主要内容,如果未能解决你的问题,请参考以下文章
在 Material-UI 中使用 React 的 'ref' 属性
Material Design UI素材库React版--定制
React + Material-UI |如何创建水平滚动卡片?