أريد أن أجعل كل ListItem
في List
إلى Link
.
لدي مكون Drawer
مكون من List
،
هذه القائمة تتكون من 4 ListItem
s.
ما أريد تحقيقه هو تحويل كل ListItem
إلى جهاز توجيه React Link
.
حاولت تعديل طريقة onClick للدرج ، والحصول على معرف عنصر القائمة الذي تم النقر عليه ثم تغيير موقع النافذة برمجيًا بناءً على المعرف.
لكنني أعتقد أن هذا النهج أكثر استفزازًا من مفاهيم التفاعل.
حاولت أيضًا إضافة Link
إلى component
prop في ListItem
، لكن نتج عن ذلك خطأ. (لقد رأيت أنك استخدمت خاصية في 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 أيضًا.
أي اقتراحات أو إهمال؟
اكتشفت ذلك ، يمكنني تغليف عنصر القائمة في رابط على النحو التالي
هذا الحل ليس صالحًا من الناحية الدلالية. ألق نظرة على كيفية تعاملنا مع المشكلة في الوثائق:
يمكنك أيضًا تجربة هذا
هذا مغطى في الوثائق: 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 ، لكن ليس من الواضح كيفية استخدام NavLink
في ListItem
.
A Button
مع component
؟
وهل يتم مزج دعامات الأزرار ودعائم المكون معًا في علامة JSX نفسها؟
ما هو هذا النوع من mixin؟
لماذا معقدة للغاية؟
عند استخدام حل mehrdaad ، تبدو الروابط مثل قائمة MUI العادية ، ولكن عند استخدام component={Link}
كما اقترح oliviertassinari ، يتم
(في الصورة ، يحوم الماوس فوق "إنشاء" ولكن العنصر الثاني يحصل على التسطير ...)
ilyador تم حل مشكلة نمط ارتباط واجهة المستخدم هذه.
@ 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://codesandbox.io/s/nk834yk5pl (لا تستخدم component={Link} to="/..."
لكن هذا هو نفسه)
caub لماذا تقوم بإدخال مكون زر إضافي؟ يمكنك استخدام خاصية المكون في MenuItem.
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}} **
المكون = {Link}
زر = {صحيح}
>
import {Link} from 'react-router-dom' <ListItem component={Link} to="/" button> // or <ListItem component={props => <Link to="/" {...props} />} button>
mehrdaadoliviertassinari لقد نجحت ^ _ ^
كان هذا مثاليا بالنسبة لي. شكر!
فشلت الإجابة الأكثر تصويتًا بعد ترحيل 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 أو حل مكون حيث لا يأخذ لون نص الزر في الاعتبار لون لوحة السمات. يجب أن يكون لون النص أبيض ليطابق 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 كـ
مفتاح = {فهرس}
** {... {to: menu.link}} **
المكون = {Link}
زر = {صحيح}
>
button={true}
ببساطة يجعل سلوك واجهة المستخدم للأدراج هو نفسه سلوك عدم وجود رابط.
بالنسبة للآخرين الذين يحاولون القيام بذلك في نسخة مطبوعة:
مثال بسيط باستخدام خاصية مكون ListItem لتحديد ملف
import { NavLink } from "react-router-dom";
<List>
<ListItem button={true} {...{ component: NavLink, to: "/Somewhere" }}>
<ListItemIcon>
<ShoppingCartIcon />
</ListItemIcon>
<ListItemText primary="Orders" />
</ListItem>
</List>
أو بدلاً من ذلك إذا كنت تريد فقط استخدام وظيفة onClick في ListItem على سبيل المثال:
<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.