我试图从Material UI实现BottomNavigation组件,但是当用户使用浏览器的后退和前进按钮时我遇到了问题。
问题是,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
答案 0 :(得分:5)
只是实现了工作!
诀窍是制作一个新的导航栏组件,该组件将包装材质UI BottomNavigation
,并使用react-router-dom
的{{1}}高阶函数将其导出。然后,您可以对当前传递到props中的路由进行一些修改,并根据一组路由(哪个路由对应哪个值)来设置withRouter
组件的值。
我的代码与您最初发布的代码有些不同,我只是使用BottomNavigation
示例here和BottomNavigation
here的用法示例
这是我的实现方式:
/src/App.jsreact-router-dom
/src/components/PrimaryNav.js
import 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;
下面是我的版本号,以供参考:
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);
答案 1 :(得分:1)
刚刚为这个 here 找到了一个非常巧妙的解决方案:
本质上,您只需在每次渲染时创建一个 pathname
常量,使用 window.location.pathname
并确保每个 <BottomNavigationAction />
的 value prop 设置为与路由相同(包括前面的正斜杠) ...类似:
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。
答案 2 :(得分:0)
我认为您应该避免对此组件进行内部状态管理。如果您需要了解并突出显示当前选择的路线,则可以仅使用react-router-dom中的NavigationLink而不是Link。 “活动”类将添加到相应的元素。如果只希望在检测到精确匹配时才激活导航元素,则只需注意确切的道具即可。
[更新]我输入了错误的组件名称,即NavLink,而不是NavigationLink。我的错。这是指向文档https://reactrouter.com/web/api/NavLink
的链接