Saya ingin membuat setiap ListItem
dalam komponen List
menjadi Link
.
Saya memiliki komponen Drawer
terdiri dari komponen List
,
Daftar itu terdiri dari 4 ListItem
s.
Yang ingin saya capai adalah mengonversi setiap ListItem
ke router React Link
.
Saya mencoba untuk mengubah metode onClick laci, mendapatkan Id dari ListItem yang diklik dan kemudian secara terprogram mengubah lokasi jendela berdasarkan id.
Tapi saya pikir pendekatan ini lebih jqueryish daripada konsep bereaksi.
Saya juga mencoba menambahkan Link
ke component
prop di ListItem
, tetapi menghasilkan kesalahan. (Saya telah melihat Anda telah menggunakan component
prop di dokumen).
Apa cara yang direkomendasikan untuk mencapai persyaratan ini?
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);
Saya menemukan, saya bisa membungkus ListItem
menjadi Link
sebagai berikut:
<Link to="users" style={{ textDecoration: 'none' }}>
<ListItem button >
<ListItemIcon>
<Person />
</ListItemIcon>
<ListItemText primary={<FormattedMessage id="user" />} />
</ListItem>
</Link>
Dengan pendekatan ini, metode onClick juga akan diaktifkan.
Ada saran atau perbaikan?
Saya menemukan, saya bisa membungkus ListItem di Link sebagai berikut
Solusi ini tidak valid secara semantik. Lihat cara kami menangani masalah di dokumentasi:
Anda juga bisa mencoba yang ini
Ini tercakup dalam dokumentasi: 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>
);
}
Saya tidak melihatnya di dokumen:
https://material-ui-next.com/demos/lists/
https://material-ui-next.com/demos/drawers/
Ini adalah hal yang umum saat menggunakan React Router, tetapi tidak jelas bagaimana menggunakan NavLink
dalam ListItem
.
A Button
dengan component
prop?
Dan alat peraga tombol dan alat peraga komponen dicampur bersama pada tag JSX yang sama?
Mixin macam apa ini?
Mengapa begitu rumit?
Saat menggunakan solusi @mehrdaad , component={Link}
seperti yang disarankan @oliviertassinari , gayanya menjadi kacau:
(Pada gambar, mouse mengarah ke "Build", tetapi item kedua mendapat garis bawah ...)
@ilyador Masalah gaya tautan UI ini telah diselesaikan.
@ zhangwei900808 Tidak, itu masih salah secara semantik, itu menghasilkan <ul><a ..>...
https://codesandbox.io/s/lpwq74p30m
Cukup gunakan jawaban yang disediakan di atas
@oliviertassinari Apakah ada cara yang lebih mudah untuk dilakukan:
const styles = {
li: {
'&:hover': {
backgroundColor: 'transparent',
},
},
};
// ...
<MenuItem disableGutters className={classes.li}>
<Button component={Link} to="/logout" ...
Untuk menghindari efek hover ganda, pada MenuItem
dan pada Button
(yang masih memiliki sedikit selokan / bantalan, masalah lain)
Karena ini tidak praktis
demo: https://codesandbox.io/s/nk834yk5pl (tidak menggunakan component={Link} to="/..."
tapi itu sama)
@caub Mengapa Anda memperkenalkan komponen Tombol tambahan? Anda dapat menggunakan properti komponen pada MenuItem.
@oliviertassinari karena ul > a
bukan html5 valid https://codesandbox.io/s/lpwq74p30m
@caub nav > a
valid.
Oke, terima kasih, baik https://codesandbox.io/s/lpwq74p30m
Inilah solusi yang memecahkan masalah saya
<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>
Jadi gunakan saja ListItem sebagai
** {... {to: menu.link}} **
komponen = {Link}
tombol = {true}
>
import {Link} from 'react-router-dom' <ListItem component={Link} to="/" button> // or <ListItem component={props => <Link to="/" {...props} />} button>
@mehrdaad @oliviertassinari Berhasil ^ _ ^
Ini sempurna untukku. Terima kasih!
Jawaban yang paling banyak dipilih gagal setelah migrasi MUI v4 (saya menggunakan 4.3.1) karena "Komponen fungsi tidak dapat diberikan referensi. Upaya untuk mengakses referensi ini akan gagal. Apakah Anda bermaksud menggunakan React.forwardRef ()?"
Saya telah mengganti komponen NavLink
menjadi pembungkus seperti ini:
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
Pemakaian:
<ListItem
button
component={NavLinkMui}
to='/'
>
<ListItemIcon>
<SlideshowIcon />
</ListItemIcon>
</ListItem>
@HugoGresse Ya, Anda perlu menggunakan API ref maju. Anda seharusnya dapat menemukan contoh di dokumentasi. Saya telah memperbarui https://github.com/mui-org/material-ui/issues/7956#issuecomment -326908167 dengan jawaban terkini. Beri tahu kami jika tidak apa-apa.
@oliviertassinari melakukannya.
Saya masih mengalami beberapa masalah dengan solusi forwardRef atau Komponen dimana warna teks Tombol tidak memperhitungkan warna palet tema. Warna teks harus putih agar cocok dengan palette.type: 'dark'
, tetapi putih.
Mungkin terkait dengan perubahan pada MUI karena tanpa properti component
saya masih mengalami masalah.
Bagi mereka yang membaca di sini, Anda dapat meneruskan props tambahan ke ListItemText ...
<ListItemText
primaryTypographyProps={{
color: 'textPrimary'
}}
primary="Dashboard"
/>
BTW, contoh Anda sekarang ada di TS.
Inilah solusi yang memecahkan masalah saya
<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>
Jadi gunakan saja ListItem sebagai
key = {index}
** {... {to: menu.link}} **
komponen = {Link}
tombol = {true}
>
button={true}
membuat perilaku UI laci sama dengan tanpa tautan.
Untuk orang lain mencoba melakukan ini di Ketikan:
Contoh sederhana yang menggunakan properti komponen ListItem untuk menentukan file
import { NavLink } from "react-router-dom";
<List>
<ListItem button={true} {...{ component: NavLink, to: "/Somewhere" }}>
<ListItemIcon>
<ShoppingCartIcon />
</ListItemIcon>
<ListItemText primary="Orders" />
</ListItem>
</List>
atau sebagai alternatif jika Anda hanya ingin menggunakan fungsi onClick pada ListItem misalnya:
<List>
<ListItem button={true} {...{ onClick: () => alert("foo") }}>
<ListItemIcon>
<DashboardIcon />
</ListItemIcon>
<ListItemText primary="Dashboard" />
</ListItem>
</List>
``
Ini berhasil untuk saya
const NavLinkMui = React.forwardRef((props, ref) => (
<NavLink {...props} activeClassName="Mui-selected" ref={ref} />
))
<ListItem button component={NavLinkMui} to={to}>{text}</ListItem>
Jawaban yang paling banyak dipilih gagal setelah migrasi MUI v4 (saya menggunakan 4.3.1) karena "Komponen fungsi tidak dapat diberikan referensi. Upaya untuk mengakses referensi ini akan gagal. Apakah Anda bermaksud menggunakan React.forwardRef ()?"
Saya telah mengganti komponen
NavLink
menjadi pembungkus seperti ini: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
Pemakaian:
<ListItem button component={NavLinkMui} to='/' > <ListItemIcon> <SlideshowIcon /> </ListItemIcon> </ListItem>
Terima kasih @HugoGresse Ini bekerja dengan baik :-)
Komentar yang paling membantu
Ini tercakup dalam dokumentasi: https://material-ui.com/components/buttons/#third -party-routing-library.