List
各ListItem
をLink
コンポーネントにしたいと思います。
私が持っているDrawer
構成部品List
、コンポーネントを
そのリストは4つのListItem
構成されています。
私が達成したいのは、各ListItem
をReactルーターLink
変換することです。
ドロワーのonClickメソッドを変更し、クリックされたListItemのIDを取得してから、IDに基づいてウィンドウの場所をプログラムで変更しようとしました。
しかし、このアプローチは、reactの概念よりもjqueryishだと思います。
また、 ListItem
component
プロップにLink
を追加しようとしましたが、エラーが発生しました( component
プロップでを使用したことがあります)ドキュメント)。
この要件を達成するための推奨される方法は何ですか?
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をリンクでラップできることがわかりました。
このソリューションは意味的に有効ではありません。 ドキュメントで問題をどのように処理するかをご覧ください。
これも試すことができます
これについては、 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/
これはReactRouterを使用する場合の一般的なことですが、 ListItem
NavLink
を使用する方法が明確ではありません。
Button
とcomponent
小道具?
そして、ボタンの小道具とコンポーネントの小道具は同じJSXタグで一緒に混合されていますか?
この種のミックスインとは何ですか?
なぜそんなに複雑なのですか?
@mehrdaadのソリューションを使用すると、リンクは通常のMUIリストのように見えますが、 @ oliviertassinariが提案したようにcomponent={Link}
を使用すると、スタイルが台無しになります。
(画像では、マウスは[ビルド]にカーソルを合わせていますが、2番目の項目には下線が引かれています...)
@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なぜ追加のボタンコンポーネントを導入するのですか? MenuItemのcomponentプロパティを使用できます。
@oliviertassinari ul > a
が無効であるためhtml5 https://codesandbox.io/s/lpwq74p30m
@caub nav > a
は有効です。
わかりました、ありがとう、元気ですhttps://codesandbox.io/s/lpwq74p30m
これが私の問題を解決した解決策です
<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を次のように使用します。
** {... {to:menu.link}} **
component = {リンク}
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はい、 https://github.com/mui-org/material-ui/issues/7956#issuecomment-326908167を最新の回答で更新しました。 大丈夫かどうかお知らせください。
@oliviertassinariそれはしました。
ボタンのテキストの色がテーマパレットの色を考慮していない、forwardRefソリューションまたはComponent1のいずれかでまだ問題が発生しています。 テキストの色はpalette.type: 'dark'
に一致するように白である必要がありますが、白です。
component
小道具がなくても問題が解決しないため、おそらくMUIの変更にリンクされています。
ここを読んでいる人のために、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を次のように使用します。
key = {index}
** {... {to:menu.link}} **
component = {リンク}
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のドキュメントで説明されています。