你如何获得 Material-UI 选项卡以与 react-router 一起工作?
How do you get Material-UI Tabs to work with react-router?
我正在尝试让 Material-UI 选项卡与路由一起工作,当路由正在工作并显示所选选项卡时,在选项卡之间导航的流畅动画不再有效.我如何使用带有 Material-UI 选项卡的 React 路由器来保持选项卡动画正常工作?
截至目前,我的 HomeHeader.js 中有选项卡,我正在使用此组件将 vale 作为 props 传递下去,以更改值,从而更改所选选项卡。
为简单起见,我简化了代码以显示我想要链接的选项卡。
这是我的代码:
Header.js(带标签的组件):
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Link } from 'react-router-dom'
class HomeHeader extends Component {
state = {
value: false
};
handleChange = (event, value) => {
this.setState({ value })
};
render() {
const { classes, value } = this.props
return (
<AppBar className={classes.appBar} elevation={this.props.elevation}>
<Hidden smDown>
<Grid container justify="space-between" alignItems="center">
<Tabs value={value} onChange={this.handleChange}>
<Tab label="monitor" component={Link} to="/monitor" />
<Tab label="sensor" component={Link} to="/sensor" />
</Tabs>
</Grid>
</Hidden>
</AppBar>
)
}
}
export default withStyles(styles)(HomeHeader)
选项卡 1 组件(将值作为道具传递给 HomeHeader.js):
import React from 'react'
import HomeHeader from '../components/HomeHeader'
class SensorProductPage extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
render() {
return (
<div>
<HomeHeader value={1} />
<div> Hello </div>
</div>
);
}
}
export default SensorProductPage
Tab 2 组件(将值作为道具传递给 HomeHeader.js):
import React from 'react'
import HomeHeader from '../components/HomeHeader'
class MonitorProductPage extends React.PureComponent {
render() {
return (
<div>
<HomeHeader value={0} />
<div> Hello </div>
</div>
);
}
}
export default MonitorProductPage
至于上面的当前结构,您可以看到 "tabs" 随着路由的变化而重新呈现。
React 的方式是由组件持有组件构建的,因此如果您更改一个组件,它的所有子组件都会被渲染。
所以在你的例子中,组件的结构是这样的:
MainApp >
Route('monitor') > MonitorProductPage > HomeHeader
Route('sensor') > SensorProductPage > HomeHeader
你可以在这个例子中看到,当你改变一条路线时,你改变了所有的内容并且需要重新渲染一个新的HomeHeader
。
顺便说一下,我将构建它以确保 HomeHeader
将被创建一次并且只有道具会改变。 (对于性能和这里的问题)
是这样的:
MainApp >
Route('innerpage/*') > InnerPage >
> MonitorProductPage
> SensorProductPage
在 React 路由器中点赞这段代码 dom
https://reacttraining.com/react-router/web/example/route-config
这意味着您只有一条路线可以捕获那些内页,它可以像上面那样,或者捕获所有 (*)
然后你将在 InnerPage 中有另一个路由器,它将决定显示哪个页面。
const routes = [
{
path: "/innerpage",
component: InnerPage
},
{
path: "/monitor",
component: MonitorProductPage,
},
{
path: "/sensor",
component: SensorProductPage
}
];
和组件 "InnerPage" 将呈现 HomeHeader
并且在其内部将具有决定其 "body"
的路由器
您在此处使用路由的方式效率低下。
应该是Tabs实现在一个地方,而且只在一个地方这样(干脆不用每页都用HomeHeader):
<BrowserRouter>
<div className={classes.root}>
<AppBar position="static" color="default">
<Tabs
value={this.state.value}
onChange={this.handleChange}
indicatorColor="primary"
textColor="primary"
fullWidth
>
<Tab label="Item One" component={Link} to="/one" />
<Tab label="Item Two" component={Link} to="/two" />
</Tabs>
</AppBar>
<Switch>
<Route path="/one" component={PageShell(ItemOne)} />
<Route path="/two" component={PageShell(ItemTwo)} />
</Switch>
</div>
</BrowserRouter>
如您所见,选项卡要求 link 和开关渲染组件中的路由
我用这篇文章的动画:https://blog.logrocket.com/routes-animation-transitions-in-react-router-v4-9f4788deb964
他们在这里使用 react-addons-css-transition-group
请在演示中找到动画index.css文件
我从 HOC 包装页面以简化路由(PageShell 组件)
这是一个工作示例:https://codesandbox.io/s/04p1v46qww
希望这会给你一个良好的开端
要跟踪活动选项卡,您可以使用位置作为选项卡值。并使用路由器位置作为 Tabs 组件的值。通过这种方式,您可以立即获得更改选项卡动画,并在直接加载页面时突出显示活动选项卡。
export const Module: React.FC<IModuleProps> = props => {
const match = useRouteMatch();
const location = useLocation();
return (
<>
<Tabs value={location.pathname} >
<Tab label="Dashboard" component={Link} to={`${match.url}/dashboard`} value={`${match.url}/dashboard`} />
<Tab label="Audit Results" component={Link} to={`${match.url}/audit-results`} value={`${match.url}/audit-results`} />
</Tabs>
<Switch>
<Route path={`${match.url}/dashboard`}>
<Dashboard />
</Route>
<Route path={`${match.url}/audit-results`}>
<AuditResults />
</Route>
<Route path={`${match.url}`}>
<Dashboard />
</Route>
</Switch>
</>
);
}
我正在尝试让 Material-UI 选项卡与路由一起工作,当路由正在工作并显示所选选项卡时,在选项卡之间导航的流畅动画不再有效.我如何使用带有 Material-UI 选项卡的 React 路由器来保持选项卡动画正常工作?
截至目前,我的 HomeHeader.js 中有选项卡,我正在使用此组件将 vale 作为 props 传递下去,以更改值,从而更改所选选项卡。
为简单起见,我简化了代码以显示我想要链接的选项卡。
这是我的代码:
Header.js(带标签的组件):
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Link } from 'react-router-dom'
class HomeHeader extends Component {
state = {
value: false
};
handleChange = (event, value) => {
this.setState({ value })
};
render() {
const { classes, value } = this.props
return (
<AppBar className={classes.appBar} elevation={this.props.elevation}>
<Hidden smDown>
<Grid container justify="space-between" alignItems="center">
<Tabs value={value} onChange={this.handleChange}>
<Tab label="monitor" component={Link} to="/monitor" />
<Tab label="sensor" component={Link} to="/sensor" />
</Tabs>
</Grid>
</Hidden>
</AppBar>
)
}
}
export default withStyles(styles)(HomeHeader)
选项卡 1 组件(将值作为道具传递给 HomeHeader.js):
import React from 'react'
import HomeHeader from '../components/HomeHeader'
class SensorProductPage extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
render() {
return (
<div>
<HomeHeader value={1} />
<div> Hello </div>
</div>
);
}
}
export default SensorProductPage
Tab 2 组件(将值作为道具传递给 HomeHeader.js):
import React from 'react'
import HomeHeader from '../components/HomeHeader'
class MonitorProductPage extends React.PureComponent {
render() {
return (
<div>
<HomeHeader value={0} />
<div> Hello </div>
</div>
);
}
}
export default MonitorProductPage
至于上面的当前结构,您可以看到 "tabs" 随着路由的变化而重新呈现。
React 的方式是由组件持有组件构建的,因此如果您更改一个组件,它的所有子组件都会被渲染。
所以在你的例子中,组件的结构是这样的:
MainApp >
Route('monitor') > MonitorProductPage > HomeHeader
Route('sensor') > SensorProductPage > HomeHeader
你可以在这个例子中看到,当你改变一条路线时,你改变了所有的内容并且需要重新渲染一个新的HomeHeader
。
顺便说一下,我将构建它以确保 HomeHeader
将被创建一次并且只有道具会改变。 (对于性能和这里的问题)
是这样的:
MainApp >
Route('innerpage/*') > InnerPage >
> MonitorProductPage
> SensorProductPage
在 React 路由器中点赞这段代码 dom https://reacttraining.com/react-router/web/example/route-config
这意味着您只有一条路线可以捕获那些内页,它可以像上面那样,或者捕获所有 (*) 然后你将在 InnerPage 中有另一个路由器,它将决定显示哪个页面。
const routes = [
{
path: "/innerpage",
component: InnerPage
},
{
path: "/monitor",
component: MonitorProductPage,
},
{
path: "/sensor",
component: SensorProductPage
}
];
和组件 "InnerPage" 将呈现 HomeHeader
并且在其内部将具有决定其 "body"
您在此处使用路由的方式效率低下。
应该是Tabs实现在一个地方,而且只在一个地方这样(干脆不用每页都用HomeHeader):
<BrowserRouter>
<div className={classes.root}>
<AppBar position="static" color="default">
<Tabs
value={this.state.value}
onChange={this.handleChange}
indicatorColor="primary"
textColor="primary"
fullWidth
>
<Tab label="Item One" component={Link} to="/one" />
<Tab label="Item Two" component={Link} to="/two" />
</Tabs>
</AppBar>
<Switch>
<Route path="/one" component={PageShell(ItemOne)} />
<Route path="/two" component={PageShell(ItemTwo)} />
</Switch>
</div>
</BrowserRouter>
如您所见,选项卡要求 link 和开关渲染组件中的路由
我用这篇文章的动画:https://blog.logrocket.com/routes-animation-transitions-in-react-router-v4-9f4788deb964
他们在这里使用 react-addons-css-transition-group
请在演示中找到动画index.css文件
我从 HOC 包装页面以简化路由(PageShell 组件)
这是一个工作示例:https://codesandbox.io/s/04p1v46qww
希望这会给你一个良好的开端
要跟踪活动选项卡,您可以使用位置作为选项卡值。并使用路由器位置作为 Tabs 组件的值。通过这种方式,您可以立即获得更改选项卡动画,并在直接加载页面时突出显示活动选项卡。
export const Module: React.FC<IModuleProps> = props => {
const match = useRouteMatch();
const location = useLocation();
return (
<>
<Tabs value={location.pathname} >
<Tab label="Dashboard" component={Link} to={`${match.url}/dashboard`} value={`${match.url}/dashboard`} />
<Tab label="Audit Results" component={Link} to={`${match.url}/audit-results`} value={`${match.url}/audit-results`} />
</Tabs>
<Switch>
<Route path={`${match.url}/dashboard`}>
<Dashboard />
</Route>
<Route path={`${match.url}/audit-results`}>
<AuditResults />
</Route>
<Route path={`${match.url}`}>
<Dashboard />
</Route>
</Switch>
</>
);
}