【问题标题】:Material-UI / ReactJS - Open Nested List based on URLMaterial-UI / ReactJS - 基于 URL 打开嵌套列表
【发布时间】:2021-02-10 19:17:02
【问题描述】:

我正在使用带有 Material-UI 的 ReactJS。如何使 MUI nested list 根据 URL 打开某些项目?在下面的代码示例中,如果有人在 /inbox/starred/ 上,那么我希望 Inbox 打开并且 Starred 处于活动状态。我玩过 React Router Nested Routes,但无法弄清楚。

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import ListSubheader from '@material-ui/core/ListSubheader';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Collapse from '@material-ui/core/Collapse';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import DraftsIcon from '@material-ui/icons/Drafts';
import SendIcon from '@material-ui/icons/Send';
import ExpandLess from '@material-ui/icons/ExpandLess';
import ExpandMore from '@material-ui/icons/ExpandMore';
import StarBorder from '@material-ui/icons/StarBorder';

const useStyles = makeStyles((theme) => ({
  root: {
    width: '100%',
    maxWidth: 360,
    backgroundColor: theme.palette.background.paper,
  },
  nested: {
    paddingLeft: theme.spacing(4),
  },
}));

export default function NestedList() {
  const classes = useStyles();
  const [open, setOpen] = React.useState(true);

  const handleClick = () => {
    setOpen(!open);
  };

  return (
    <List
      component="nav"
      aria-labelledby="nested-list-subheader"
      subheader={
        <ListSubheader component="div" id="nested-list-subheader">
          Nested List Items
        </ListSubheader>
      }
      className={classes.root}
    >
      <ListItem button>
        <ListItemIcon>
          <SendIcon />
        </ListItemIcon>
        <ListItemText primary="Sent mail" />
      </ListItem>
      <ListItem button>
        <ListItemIcon>
          <DraftsIcon />
        </ListItemIcon>
        <ListItemText primary="Drafts" />
      </ListItem>
      <ListItem button onClick={handleClick}>
        <ListItemIcon>
          <InboxIcon />
        </ListItemIcon>
        <ListItemText primary="Inbox" />
        {open ? <ExpandLess /> : <ExpandMore />}
      </ListItem>
      <Collapse in={open} timeout="auto" unmountOnExit>
        <List component="div" disablePadding>
          <ListItem button className={classes.nested}>
            <ListItemIcon>
              <StarBorder />
            </ListItemIcon>
            <ListItemText primary="Starred" />
          </ListItem>
        </List>
      </Collapse>
    </List>
  );
}

【问题讨论】:

    标签: reactjs routes material-ui nested-lists


    【解决方案1】:

    对于这个任务,我建议使用react-router 的 URL 参数。

    首先,您需要将路线更改为以下内容:

    <Route path="/:drawer/:subDrawer" children={<NestedList />} />
    

    注意上述路径中的:drawer:subDrawer。这就是我们要用来知道我们在哪条路线上的东西。

    然后,在您的组件中,使用 URL 参数中的 drawersubDrawer,如下所示(出于演示目的,我隐藏了一些内容,但您明白了):

    // ...other imports
    import { useParams } from 'react-router-dom';
    
    export default function NestedList() {
      const classes = useStyles();
      
      const { drawer, subDrawer } = useParams();
      
      return (
        <List>
          {//... other stuff}
    
          <ListItem button onClick={handleClick}>
            <ListItemIcon>
              <InboxIcon />
            </ListItemIcon>
            <ListItemText primary="Inbox" />
            {// changed the logic here}
            {drawer === 'inbox' ? <ExpandLess /> : <ExpandMore />}
          </ListItem>
          <Collapse in={open} timeout="auto" unmountOnExit>
            <List component="div" disablePadding>
              {// changed the logic here}
              <ListItem
                selected={subDrawer === 'starred'}
                button className={classes.nested}
              >
                <ListItemIcon>
                  <StarBorder />
                </ListItemIcon>
                <ListItemText primary="Starred" />
              </ListItem>
            </List>
          </Collapse>
        </List>
      );
    }
      
    

    现在,由于我们依赖于知道打开哪个抽屉的路径,我们应该为每个菜单项更改onClick 以将用户重定向到适当的路径。也许当用户点击Sent mail时,页面会被重定向到/sent-mail,对应的已发送邮件按钮如下所示:

          <ListItem button selected={subDrawer === 'sent-item'}>
            <ListItemIcon>
              <SendIcon />
            </ListItemIcon>
            <ListItemText primary="Sent mail" />
          </ListItem>
    

    等等……

    【讨论】:

    • 谢谢。我能够使用 location.pathname.startsWith('/Sent/') 让它工作
    猜你喜欢
    • 2021-01-07
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 2021-10-11
    • 2021-03-05
    • 1970-01-01
    相关资源
    最近更新 更多