【问题标题】:How to render different component onClick using React material-ui Drawer list?如何使用 React material-ui Drawer 列表渲染不同的组件 onClick?
【发布时间】:2019-12-04 23:41:21
【问题描述】:

我正在使用 React material-ui 包进行仪表板设计。我有一个应用栏和一个带有不同项目列表的抽屉。当我单击抽屉中的项目时,我想在抽屉的“ma​​in”标签内呈现相应的组件。

App.js 组件是基于类的。而且我有所有其他路线和功能的功能组件。

import React, { useState } from "react";
import { makeStyles, useTheme } from '@material-ui/core/styles';
import { Link } from 'react-router-dom'
import { useAuthState } from '../contexts/AuthContext';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import DraftsIcon from '@material-ui/icons/Drafts';

import {MenuItem, MenuList, ListItemIcon, ListItemText
        , Drawer, ListItem, List, Divider, CssBaseline
        , Paper, IconButton, Typography, AppBar, Toolbar
        , Button, Input } from '@material-ui/core';

const drawerWidth = 200;

const useStyles = makeStyles(theme => ({
    root: {
      display: 'flex',
    },
    appBar: {
        width: `calc(100% - ${drawerWidth}px)`,
        marginLeft: drawerWidth,
    },
    menuButton: {
      marginRight: theme.spacing(2),
      fontSize: "16px",
      color: "#fff",
    },
    hide: {
        display: 'none',
    },
    drawer: {
        width: drawerWidth,
        flexShrink: 0,
    },
    drawerPaper: {
        width: drawerWidth,
    },
    toolbar: theme.mixins.toolbar,

    content: {
        flexGrow: 1,
        backgroundColor: theme.palette.background.default,
        padding: theme.spacing(3),
    },

    title: {
        flexGrow: 1,
        fontSize: "18px",
    },
    LinkBar: {

    },
    SideBarFont: {
        fontSize: "14px",
    },
}));


export default function Dashboard(props) {
    const classes = useStyles();
    const theme = useTheme();
    const { setUser } = useAuthState();
    const [open, setOpen] = React.useState(false);

    return (
        <div className={classes.root}>
            <CssBaseline />
            <AppBar 
                className={classes.appBar}
                position="fixed"
            >
                <Toolbar>
                    <Typography variant="h6" className={classes.title} noWrap>
                        Dashboard
                    </Typography>

                    <Button color="inherit">Logout</Button>

                </Toolbar>
            </AppBar>

            <Drawer
                className={classes.drawer}
                variant="permanent"
                anchor="left"
                classes={{
                    paper: classes.drawerPaper,
                }}
                >
                <div className={classes.toolbar} />
                <Divider />

                <List component="nav" aria-label="main mailbox folders">
                    <ListItem button>
                        <ListItemIcon>
                            <InboxIcon />
                        </ListItemIcon>

                        <ListItemText disableTypography className={classes.SideBarFont} primary="User" />
                    </ListItem>
                    <ListItem button>
                        <ListItemIcon>
                            <DraftsIcon />
                        </ListItemIcon>

                        <ListItemText disableTypography className={classes.SideBarFont}  primary="Account" />
                    </ListItem>

                    <ListItem button>
                        <ListItemIcon>
                            <DraftsIcon />
                        </ListItemIcon>

                        <ListItemText disableTypography className={classes.SideBarFont}  primary="Customer Support" />
                    </ListItem>

                    <ListItem component={Link} to="/inventory" button>
                        <ListItemIcon>
                            <DraftsIcon />
                        </ListItemIcon>

                        <ListItemText disableTypography className={classes.SideBarFont}  primary="Inventory" />
                    </ListItem>
                </List>

            </Drawer>

            <main className={classes.content}>
                <div className={classes.toolbar} />
                <h1>Hello</h1>
                <Typography paragraph>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
                    ut labore et dolore magna aliqua. Rhoncus dolor purus non enim praesent elementum
                </Typography>

            </main>           

        </div>
    );
}

我在各自的 jsx 文件中有用户、库存、客户支持、帐户的功能组件。当用户点击抽屉列表项时,我如何呈现或在“ma​​in”内?

有关用户界面,请参见下文。我想在渲染 Hello 的地方渲染。

【问题讨论】:

    标签: html reactjs react-router material-ui


    【解决方案1】:

    首先,您需要做一些事情。

    1. main 中创建要呈现的组件
    2. 将这些组件导入Dashboard 组件

    由于您已经在组件中使用useState,因此您需要设置另一个useState

    在您的ListItem 上,您可以将onClick 添加到组件并执行useState 函数将该状态设置为所述组件。

    main 中,您需要添加某种三元或检查器来确定要显示的组件。

    我在这里删除了一些项目,但这是给您的一个简短示例:

    import User from '/path/to/user/component';
    import Account from '/path/to/account/component';
    ...
    export default function Dashboard(props) {
      const [component, setComponent] = useState('user')
      ...
      return (
        ...
        <ListItem button onClick={() => setComponent('account')}>
          <ListItemIcon>
            <DraftsIcon />
          </ListItemIcon>
    
          <ListItemText disableTypography className={classes.SideBarFont} primary="Account" />
        </ListItem >
        ...
    
          <main className={classes.content}>
            <div className={classes.toolbar} />
            {
              component === 'user' ?
              <User />
              :
              component === 'account' ?
              :
              <Account />
              ...
            }
          </main>
    
        </div>
      );
    }
    

    是的,在main 中有一种更简洁的方式来进行组件渲染,但这应该让您知道从哪里开始

    【讨论】:

    • 您好,感谢您的回复。我根据您的建议更改了代码: 列表项>。但是在 serComponent('user') 的行上抛出了 Too-many re-renders 的错误
    • @dhavalnc1 抱歉,我刚刚进行了编辑,点击会在我查看后触发很多次,将其更改为 onClick={() =&gt; setComponent('user')} 以便它只触发一次
    • 太棒了。它现在适用于更改。非常感谢。
    • 上述建议非常有效。现在,当我渲染不同的组件时,有什么方法可以添加/制作新的动态路由?例如,当用户点击左侧边栏中的 Account 时,我想显示类似“www.abc.com/accounts”的 URL。我知道我们可以使用 声明 Routes。但问题是我的路由将根据登录后的 JSON 响应动态。我无法定义静态路由。我不知道我是否缺少 react-router 的核心知识。我应该在谷歌搜索什么来找到这个问题的答案?
    • @dhavalnc1 我会建议像 React Material UI Drawer Router 这样的搜索,它会返回如下内容:stackoverflow.com/questions/50801093/… 以及您也可以遵循的其他 youtube 教程
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 2018-01-11
    • 2021-12-19
    • 1970-01-01
    • 2018-08-18
    • 2021-10-14
    相关资源
    最近更新 更多