我想将List
中的每个ListItem
List
转换为Link
组件。
我有一个由Drawer
组件组成的List
组件,
该列表由4个ListItem
s组成。
我想要实现的是将每个ListItem
转换为React路由器Link
。
我试图修改抽屉的onClick方法,获取被单击的ListItem的ID,然后根据ID以编程方式更改窗口的位置。
但是我确实认为这种方法比react概念更令人费解。
我也尝试添加Link
至component
的道具ListItem
,但它造成的错误。(我已经看到你已经使用了在component
的道具docs)。
达到此要求的推荐方法是什么?
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Drawer from 'material-ui/Drawer';
import List, { ListItem, ListItemIcon, ListItemText } from 'material-ui/List';
import Face from 'material-ui-icons/Face';
import Person from 'material-ui-icons/Person';
import Assignment from 'material-ui-icons/Assignment';
import Link from 'react-router-dom/Link';
import { FormattedMessage } from 'react-intl';
const styles = {
list: {
width: 250,
flex: 'initial',
},
};
class UndockedDrawer extends Component {
constructor() {
super();
this.onClick = this.onClick.bind(this);
}
onClick(e, data) {
console.log(data);
this.props.onRequestClose();
}
render() {
const classes = this.props.classes;
const sidebarListItems = (
<div>
<ListItem button >
<ListItemIcon>
<Person />
</ListItemIcon>
<ListItemText primary={<FormattedMessage id="user" />} />
</ListItem>
<ListItem button>
<ListItemIcon>
<Assignment />
</ListItemIcon>
<ListItemText primary={<FormattedMessage id="consultant" />} />
</ListItem>
<ListItem button>
<ListItemIcon>
<Face />
</ListItemIcon>
<ListItemText primary={<FormattedMessage id="student" />} />
</ListItem>
</div>
);
const sidebarList = (
<div>
<List className={classes.list} >
{sidebarListItems}
</List>
</div>
);
return (
<div>
<Drawer
anchor="right"
open={this.props.open}
onRequestClose={this.props.onRequestClose}
onClick={this.onClick}
>
{sidebarList}
</Drawer>
</div>
);
}
}
UndockedDrawer.propTypes = {
classes: PropTypes.shape({}).isRequired,
open: PropTypes.bool.isRequired,
onRequestClose: PropTypes.func.isRequired,
};
export default withStyles(styles)(UndockedDrawer);
我想通了,我可以将ListItem
包裹在Link
,如下所示:
<Link to="users" style={{ textDecoration: 'none' }}>
<ListItem button >
<ListItemIcon>
<Person />
</ListItemIcon>
<ListItemText primary={<FormattedMessage id="user" />} />
</ListItem>
</Link>
通过这种方法,也会触发onClick方法。
有什么建议或改进吗?
我想通了,我可以将ListItem包装在Link中,如下所示
该解决方案在语义上无效。 看一下我们如何处理文档上的问题:
你也可以试试这个
在文档中对此进行了介绍: https: //material-ui.com/components/buttons/#third -party-routing-library。
import React from 'react';
import { MemoryRouter as Router } from 'react-router';
import { Link, LinkProps } from 'react-router-dom';
import ListItem from '@material-ui/core/ListItem';
import { Omit } from '@material-ui/types';
// The usage of React.forwardRef will no longer be required for react-router-dom v6.
// see https://github.com/ReactTraining/react-router/issues/6056
const AdapterLink = React.forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => (
<Link innerRef={ref as any} {...props} />
));
const CollisionLink = React.forwardRef<HTMLAnchorElement, Omit<LinkProps, 'innerRef' | 'to'>>(
(props, ref) => <Link innerRef={ref as any} to="/getting-started/installation/" {...props} />,
);
export default function ButtonRouter() {
return (
<Router>
<ListItem color="primary" component={AdapterLink} to="/">
Simple case
</ListItem>
<ListItem component={CollisionLink}>Avoids props collision</ListItem>
</Router>
);
}
我在文档中没有看到它:
https://material-ui-next.com/demos/lists/
https://material-ui-next.com/demos/drawers/
这在使用React Router时很常见,但尚不清楚如何在ListItem
使用NavLink
ListItem
。
一个Button
与component
道具?
而且按钮道具和组件道具在同一个JSX标签上混合在一起吗?
这种混合是什么?
为什么这么复杂?
当使用@mehrdaad的解决方案时,链接看起来像普通的MUI列表,但是当使用component={Link}
作为@oliviertassinari建议时,样式会混乱:
(在图像中,鼠标悬停在“ Build”上,但是第二项获得了下划线...)
@ilyador此UI链接样式问题已解决。
@ zhangwei900808不,在语义上还是错误的,它会生成<ul><a ..>...
https://codesandbox.io/s/lpwq74p30m
只需使用上面提供的答案
@oliviertassinari是否会有更简单的方法:
const styles = {
li: {
'&:hover': {
backgroundColor: 'transparent',
},
},
};
// ...
<MenuItem disableGutters className={classes.li}>
<Button component={Link} to="/logout" ...
为避免出现双重悬停效果,请在MenuItem
和Button
(它们仍然有少量装订线/填充,这是另一个问题)
因为这很麻烦
演示: https : component={Link} to="/..."
但这是相同的)
@caub为什么要引入一个额外的Button组件? 您可以在MenuItem上使用component属性。
@oliviertassinari,因为ul > a
无效html5 https://codesandbox.io/s/lpwq74p30m
@caub nav > a
有效。
这是解决我的问题的解决方案
<List>
{menus.map((menu: any, index: any) => {
return (
<ListItem
key={index}
{...{ to: menu.link }}
component={Link}
button={true}
>
<ListItemIcon>{menu.icon}</ListItemIcon>
<ListItemText primary={menu.text} />
</ListItem>
);
})}
</List>
因此,只需将ListItem用作
** {... {至:menu.link}} **
组件= {链接}
button = {true}
>
import {Link} from 'react-router-dom' <ListItem component={Link} to="/" button> // or <ListItem component={props => <Link to="/" {...props} />} button>
@mehrdaad @oliviertassinari工作了^ _ ^
这对我来说是完美的。 谢谢!
投票最多的答案在MUI v4迁移后失败(我在4.3.1上),原因是“无法为功能组件提供引用。尝试访问该引用将失败。您是要使用React.forwardRef()吗?”
我已经将NavLink
组件替换为包装器,如下所示:
import React, { Component } from "react"
import { NavLink } from "react-router-dom"
/**
* React Router Nav Link wrapper to forward the ref to fix "Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?"
*
* From https://material-ui.com/guides/composition/#caveat-with-refs
*/
class NavLinkMui extends Component {
render() {
const { forwardedRef, ...props } = this.props
return <NavLink {...props} ref={forwardedRef} />
}
}
export default NavLinkMui
用法:
<ListItem
button
component={NavLinkMui}
to='/'
>
<ListItemIcon>
<SlideshowIcon />
</ListItemIcon>
</ListItem>
@HugoGresse是的,您需要使用前向引用API。 您应该能够在文档中找到示例。 我已经使用最新答案更新了https://github.com/mui-org/material-ui/issues/7956#issuecomment -326908167。 让我们知道是否可以。
@oliviertassinari它做到了。
我仍然对forwardRef解决方案或组件一有一些问题,其中Button文本颜色未考虑主题调色板颜色。 文字颜色应为白色,以匹配palette.type: 'dark'
,但为白色。
可能与MUI的更改有关,因为没有component
道具,我仍然遇到问题。
对于在这里阅读的人,可以将其他道具传递给ListItemText ...
<ListItemText
primaryTypographyProps={{
color: 'textPrimary'
}}
primary="Dashboard"
/>
顺便说一句,您的示例现在在TS中。
这是解决我的问题的解决方案
<List> {menus.map((menu: any, index: any) => { return ( <ListItem key={index} {...{ to: menu.link }} component={Link} button={true} > <ListItemIcon>{menu.icon}</ListItemIcon> <ListItemText primary={menu.text} /> </ListItem> ); })} </List>
因此,只需将ListItem用作
键= {索引}
** {... {至:menu.link}} **
组件= {链接}
button = {true}
>
button={true}
只是使抽屉的UI行为与没有链接相同。
对于尝试在Typescript中执行此操作的其他人:
使用ListItem组件属性指定一个简单示例
import { NavLink } from "react-router-dom";
<List>
<ListItem button={true} {...{ component: NavLink, to: "/Somewhere" }}>
<ListItemIcon>
<ShoppingCartIcon />
</ListItemIcon>
<ListItemText primary="Orders" />
</ListItem>
</List>
或者,如果您只想在ListItem上使用onClick函数,例如:
<List>
<ListItem button={true} {...{ onClick: () => alert("foo") }}>
<ListItemIcon>
<DashboardIcon />
</ListItemIcon>
<ListItemText primary="Dashboard" />
</ListItem>
</List>
```
这对我有用
const NavLinkMui = React.forwardRef((props, ref) => (
<NavLink {...props} activeClassName="Mui-selected" ref={ref} />
))
<ListItem button component={NavLinkMui} to={to}>{text}</ListItem>
投票最多的答案在MUI v4迁移后失败(我在4.3.1上),原因是“无法为功能组件提供引用。尝试访问该引用将失败。您是要使用React.forwardRef()吗?”
我已经将
NavLink
组件替换为包装器,如下所示:import React, { Component } from "react" import { NavLink } from "react-router-dom" /** * React Router Nav Link wrapper to forward the ref to fix "Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?" * * From https://material-ui.com/guides/composition/#caveat-with-refs */ class NavLinkMui extends Component { render() { const { forwardedRef, ...props } = this.props return <NavLink {...props} ref={forwardedRef} /> } } export default NavLinkMui
用法:
<ListItem button component={NavLinkMui} to='/' > <ListItemIcon> <SlideshowIcon /> </ListItemIcon> </ListItem>
谢谢@HugoGresse这工作得很好:-)
最有用的评论
在文档中对此进行了介绍: https: //material-ui.com/components/buttons/#third -party-routing-library。