嗨,我正在查看菜单项的当前实现,并注意到没有实际链接(意思是 html <a>
标记)。 结果,例如,即使在导航栏中也没有实际的链接,并且通过 onclick 事件管理到其他页面的转换。
我认为拥有链接将是一种改进,尤其是考虑到服务器端呈现的页面。
你认为这是有道理的,还是你有具体的理由不朝这个方向发展?
我也想知道这个。 我在我的应用程序中使用服务器端渲染,这是需要研究的。
使用具有href
属性的锚元素也将提高可访问性并允许人们使用他们习惯的浏览器行为(例如 ⌘-单击以在新选项卡中打开)。
+1
+1
+1
+1
+1
+1
+1
@ecesena你认为这仍然是新的MenuItem
组件的问题吗? 见这里。 MenuItem
可以被<a>..</a>
包围,不是吗?
这可以通过@shaurya947 的建议来实现。
我试图在我的 LeftNav 中使用MenuItems
,如下所示:
let menuItems = (
<div>
<MenuItem primaryText="Doors" leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} /></a>
<MenuItem primaryText="Load" leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
<MenuItem primaryText="Notes" leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
<MenuItem primaryText="Alerts" leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
<MenuItem primaryText="Admin" leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
</div>
);
return (
<LeftNav
ref="leftNav"
docked={false}
onChange={this._onLeftNavChange}
>
{menuItems}
</LeftNav>
)
将<a>
包裹在<MenuItem>
标记周围会引发警告validateDOMNesting(...): <a> cannot appear as a descendant of <a>. See MainLayout > a > ... > MenuItem > ListItem > EnhancedButton > a"
如果你对输出进行 React 检查,你会得到以下结果。
<a href="/">
<MenuItem..>
<ListItem..>
<div>
<EnhancedButton..>
<a>
<TouchRipple ..>
</a>
</EnhancedButton>
</div>
</ListItem>
</MenuItem>
</a>
嵌套<a>
元素是令人反感的。
<MenuItems>
在 Button 声明中生成<a>
元素。 MenuItem
使用什么道具来填充生成的<EnhancedButton>
的 href 属性?
使用 MenuItem 对象作为 LeftNav 的道具可以使链接正常工作,但我无法弄清楚如何以这种方式添加左/右图标。
IE:
let menuItems = [
{ route: '/load_areas/'+ this.state.area + '/doors', text: 'Doors' },
{ route: '/load_areas/'+ this.state.area + '/trailer_loads', text: 'Load' },
{ route: 'notes', text: 'Notes' },
{ route: 'alerts', text: 'Alerts' },
{ route: 'admin', text: 'Admin' }
];
<LeftNav
ref="leftNav"
docked={false}
menuItems={menuItems}
onChange={this._onLeftNavChange}
/>
这是一个单独的问题,请打开一个,以便我们标记它并将其添加到里程碑,tnx :grin:
使用containerElement
道具!
看:
http://stackoverflow.com/questions/32106513/material-ui-menu-using-routes/34507786#34507786
<MenuItem
containerElement={<Link to="/profile" />}
primaryText="Profile"
leftIcon={
<FontIcon className="material-icons">people</FontIcon>
} />
现在EnhancedButton
的道具linkButton
已被弃用。 当提供href
属性时,不再需要 LinkButton。 它将在 v0.16.0 中删除。
例如:
<MenuItem primaryText="Primary Text" href="/your/link" />
href 重新加载页面。 如果我想使用反应路由器怎么样
@cezarneaga试试href="#/your/link"
<MenuItem
containerElement={<Link to="/profile" />}
.../>
文档提到您还需要输入linkButton
。 如果您删除它,它可以正常工作。
@DaxChen我看到了您在 2016 年 12 月更新的 stackoverflow 答案(最近的哈哈),我想知道您是否知道这是否适用于抽屉中的 MenuItem? 我正在尝试以下操作,并且完全无法让 Link 与 MenuItem 一起工作,因为 containerElement 似乎什么也没做。
<Drawer
docked={false}
width={300}
onRequestChange={this.closeDrawer}
open={this.state.open}>
<AppBar title="Title"
/>
<MenuItem primaryText="home" containerElement={<Link to="/home" />} />
</Drawer>
containerElement 有效,但没有记录,所以我想这个线程现在必须作为官方文档。 谢谢!
嗨@Faolain !
真的很抱歉回复晚了...
我尝试使用create-react-app
在干净的应用程序上编写代码,但一切似乎都正常?!
也许你配置的react-router
不同,还是版本不同?
无论如何,这里有一个示例 Repo和Live Demo Here 。
如果您仍然找不到问题的原因,您可以提供一个示例 repo 来重现吗?
上述解决方案均不适用于 Safari 和 iOS。 所以这就是我为react-router
所做的工作
<MenuItem
onTouchTap={() => {
this._yourMethod()
browserHistory.push('/howItWorks')
}}
primaryText="Menu Link"
/>
@DaxChen感谢您的见解。 我不确定我的问题是否与您的第一个链接有关。 我已经尝试了第二个,但是一旦我添加了onTouchTap
道具, <Link />
就不再起作用了。
@DaxChen我看到您在material-ui
版本中使用~0.16.0
。 您是否尝试过最新的~0.17.0
并查看是否仍然没有问题?
@janzenz我使用的是旧版本,刚刚更新到最新的0.17.4
并且它仍然有效!
触摸! 可能是我当时的设置。 感谢您确认@DaxChen,如果我发现了真正的问题,我会回到这个帖子。
@DaxChen ,我尝试了你给我的例子,但它失败了
Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in. Check the render method of `EnhancedButton`.
at invariant (invariant.js:44)
at ReactCompositeComponentWrapper.instantiateReactComponent [as _instantiateReactComponent] (instantiateReactComponent.js:74)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:367)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at mountComponentIntoNode (ReactMount.js:104)
at ReactReconcileTransaction.perform (Transaction.js:140)
at batchedMountComponentIntoNode (ReactMount.js:126)
at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:140)
at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
at Object.batchedUpdates (ReactUpdates.js:97)
at Object._renderNewRootComponent (ReactMount.js:320)
at Object._renderSubtreeIntoContainer (ReactMount.js:401)
at Object.render (ReactMount.js:422)
at Object.<anonymous> (index.js:36)
at __webpack_require__ (bootstrap e3e2367…:555)
at fn (bootstrap e3e2367…:86)
at Object.<anonymous> (bootstrap e3e2367…:578)
at __webpack_require__ (bootstrap e3e2367…:555)
at bootstrap e3e2367…:578
at bootstrap e3e2367…:578
我的代码可在https://github.com/hhimanshu/spicyveggie/tree/cards ( cards
分支)
我不确定有什么不同,但它不起作用
@janzenz
我也尝试了browserHistory.push('/howItWorks')
并导入了import browserHistory from 'react-router-dom'
,但得到了undefuned
。
@Oduig ,
我试过#/your/link
,但它没有带我去任何地方
我试过/your/link
,但它重新加载页面,我从Material-UI
丢失了Drawer
Material-UI
这些东西都不适合我。 我的代码在https://github.com/hhimanshu/spicyveggie/tree/cards ( cards
分支),具体提交是https://github.com/hhimanshu/spicyveggie/commit/844b7b7cddf9102995cd2680a783df3b6ef48537 ,可以有人请帮忙吗?
@DaxChen ,谢谢。 就是这样。 但是,不是当我的页面加载{<Link to="/menu"/>}
,它会加载整个页面并且我的Drawer
消失了。
@hhimanshu那是因为您在\menu
路线中仅使用了Menu
组件,因此不会呈现App
。
将Menu
和Summary
嵌套在App
或一些布局组件中,并传入各自的子级。
您可以使用 react-devtools 来检查渲染的组件层次结构及其状态!
这与 material-ui 无关,请在 react-router 的教程/文档中阅读更多内容。
谢谢@DaxChen ,我将其解决为https://github.com/hhimanshu/spicyveggie/blob/master/src/index.js#L20
+1
React Router HANDLED & NOT HANDLED 链接的解决方法。
如果目标链接由 React Router 处理
MenuItemLink.js
import React from 'react';
import { MenuItem } from 'material-ui/Menu';
import { Route } from 'react-router-dom';
class MenuItemLink extends React.Component {
render() {
const {
to, also,
...rest
} = this.props;
return (
<Route
render={({ history, location }) => (
<MenuItem
onClick={() => {
history.push(to);
if (typeof also === 'function') {
also();
}
}}
{...rest}
/>
)}
/>
);
}
}
MenuItemLink.muiName = 'MenuItem';
export default MenuItemLink;
示例代码:
import MenuItemLink from './MenuItemLink';
<Menu ... >
<MenuItemLink to="/users"
also={this.handleRequestClose}>Users</MenuItemLink>
</Menu>
如果 React Router 不处理目标链接,即:请求被转发到 API 服务器或其他
点击功能:
function facebookLoginRedirect () {
if (window) window.location.href = "/api/auth/facebook"
return true;
}
示例代码:
<MenuItem onClick={ facebookLoginRedirect }>Login with Facebook</MenuItem>
我来补充一下,以防其他人也偶然发现它。
在 v3.4 上,您可以这样实现:
import { Link } from 'react-router-dom';
import MenuItem from '@material-ui/core/MenuItem';
...
<MenuItem component={Link} to="/your-path">...</MenuItem>
在不破坏菜单布局的情况下对我有用的唯一解决方案是:
```javascript
在不破坏菜单布局的情况下对我有用的唯一解决方案是:
<MenuList> <Link to='/your-path' style={{ textDecoration: 'none' }}> <MenuItem> Notifications </MenuItem> </Link> <Link to='/your-path' style={{ textDecoration: 'none' }}> <MenuItem> Profile </MenuItem> </Link> </MenuList>
@eladlevy这最终会导致语义不佳的HTML。
<ul>
<a><li/></a>
<a><li/></a>
</ul>
把它留在这里以防它帮助任何人(运行 v3.9.0)。 我需要一个<Select>
来充当react-router-dom
<Link>
的菜单。 每个链接对应一个语言设置,因此下拉列表将显示查询参数中当前语言的值。
<Select value={currentLanguage}>
{languages.map(language => (
<ListItem
button
component={btnProps => (
<Link
to={ `/things?lang=${ language }` }
{...btnProps as any}
/>
)}
value={language}
key={language}
>
{language}
</ListItem>
))}
</Select>
这是我能找到的最简洁的解决方案,它需要最少的 TypeScript 转换并保持与 Material UI 一致的视觉效果。
@goyney有解决方案,谢谢
我来补充一下,以防其他人也偶然发现它。
在 v3.4 上,您可以这样实现:
import { Link } from 'react-router-dom'; import MenuItem from '@material-ui/core/MenuItem'; ... <MenuItem component={Link} to="/your-path">...</MenuItem>
工作和清洁的解决方案,谢谢❤️
对于外部链接,您需要使用component="a"
,但也要将MenuItem
包围在<li>
:
<MenuList>
<li>
<MenuItem
component="a"
href="https://google.com"
target="_blank"
>Google</MenuItem>
</li>
</MenuList>
这会生成以下 HTML:
<ul class="MuiList-root MuiList-padding" role="menu" tabindex="-1">
<li>
<a class="[...]" tabindex="-1" aria-disabled="false" role="menuitem" href="https://google.com" target="_blank">Google</a>
</li>
</ul>
假设我有一个弹出菜单并使用
从'react-router-dom'导入{链接};
从'@material-ui/core/MenuItem'导入菜单项;
\
链接将打开 /your-path 页面,如何关闭弹出菜单?
最有用的评论
使用
containerElement
道具!看:
http://stackoverflow.com/questions/32106513/material-ui-menu-using-routes/34507786#34507786