【问题标题】:Switch function in react component not working as logic would suggest反应组件中的开关功能不按逻辑建议工作
【发布时间】:2020-09-13 00:54:22
【问题描述】:

所以我的反应代码没有按照逻辑建议执行:

我正在尝试创建一个类似于电子邮件应用程序的页面。 我在 React 中有组件,我将它们导入到我的消息(主)组件中(例如收件箱组件、发送邮件组件等)。我有一个 useState,默认设置为“收件箱”,还有一个 switch 语句,它检查哪个值处于状态并返回与该情况匹配的组件。我还有一个 onclick 功能,它根据您要查看的电子邮件选项卡(例如收件箱或垃圾箱等)更改状态值。当状态发生变化时,组件应该在我的页面渲染中运行 switch 语句并在主组件中显示正确的组件,这在大多数情况下都是如此。

当我不断在具有组件的选项卡之间切换时,我的问题出现了,它有时会转到 switch 语句的默认值,这没有意义,因为任何一个值都应该通过。

请帮忙

import React, {useState} from 'react';

// Components to be displayed
import Inbox from './Inbox';
import SendMessage from './SendMessage';

// Other components on the page which you can ignore
import Navbar from  '../Layout/Navbar';
import Copyright from '../Layout/Copyright';
import SendMail from './SendMail';

//Material ui for styling
import AppBar from '@material-ui/core/AppBar';
import CssBaseline from '@material-ui/core/CssBaseline';
import Divider from '@material-ui/core/Divider';
import Drawer from '@material-ui/core/Drawer';
import Hidden from '@material-ui/core/Hidden';
import IconButton from '@material-ui/core/IconButton';
import InboxIcon from '@material-ui/icons/MoveToInbox';
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 MailIcon from '@material-ui/icons/Mail';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Link from '@material-ui/core/Link';
import ControlPointIcon from '@material-ui/icons/ControlPoint';

const drawerWidth = 240;

const list = [
  {id: 1, title: 'Singing lessons', message: 'We are practicing at 5:00'},
  {id: 2, title: 'Meeting', message: 'Hi Guys, we can meet during lunch at Nandos'},
  {id: 3, title: 'New Product release', message: 'Hi guys, we are encouraging everyone to buy in on the new product'}
]

const useStyles = makeStyles((theme) => ({
  root: {
    display: 'flex'
  },
  drawer: {
    [theme.breakpoints.up('sm')]: {
      width: drawerWidth,
      flexShrink: 0,
      zIndex: '0'
    }
  },
  appBar: {
    [theme.breakpoints.up('sm')]: {
      width: `calc(100% - ${drawerWidth}px)`,
      marginLeft: drawerWidth,
    },
  },
  menuButton: {
    marginRight: theme.spacing(2),
    [theme.breakpoints.up('sm')]: {
      display: 'none',
    },
  },
  // necessary for content to be below app bar
  toolbar: theme.mixins.toolbar,
  drawerPaper: {
    width: drawerWidth,
  },
  content: {
    flexGrow: 1,
    padding: theme.spacing(3)
  },
  listItemStyle: {
    marginTop: '50px'
  },
  newMessage: {
    fontSize: '40px',
    backgroundColor: '#64b5f6',
    borderRadius: '50px',
    color: '#fff',
    position: 'absolute',
    bottom: '50px',
    right: '50px',
    '&:hover': {
        backgroundColor: '#1976d2'
    }
  }
}));


// Main component
const Message = (props) => {
  const { window } = props;
  const classes = useStyles();
  const theme = useTheme();
  const [mobileOpen, setMobileOpen] = useState(false);
  const [tabTracker, setTabTracker] = useState('Inbox');


  const renderSwitch = (param) => {
    switch(param) {
      case 'Inbox':
        return <Inbox />;
      case 'Send email':
        return <SendMail />;
      case 'Drafts':
        return 'Draft';
      case 'Trash':
        return 'Trash';
      case 'Spam':
        return 'Spam';
      case 'newMessage':
        return <SendMessage />;
      default:
        return 'foo';
    }
  }

  const tabControl = (e) => {
    setTabTracker(e.target.firstChild.data);
    //renderSwitch(tabTracker);
  }

  const newMsg = (e) => {
    setTabTracker(e.target.attributes[5].value);
    //renderSwitch(tabTracker);
  }

  const handleDrawerToggle = () => {
    setMobileOpen(!mobileOpen);
  };

  const drawer = (
    <div>
      <div className={classes.toolbar} />
      <Divider />
      <List className={classes.listItemStyle}>
        {['Inbox', 'Send email', 'Drafts'].map((text, index) => (
          <ListItem button key={text} onClick={tabControl}>
            <ListItemIcon>{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}</ListItemIcon>
            <ListItemText primary={text} />
          </ListItem>
        ))}
      </List>
      <Divider />
      <List>
        {['Trash', 'Spam'].map((text, index) => (
          <ListItem button key={text} onClick={tabControl}>
            <ListItemIcon>{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}</ListItemIcon>
            <ListItemText primary={text} />
          </ListItem>
        ))}
      </List>
    </div>
  );

  const container = window !== undefined ? () => window().document.body : undefined;

  return (
    <React.Fragment>
      <span>
        <Navbar />
      </span>
      <div className={classes.root}>
        <CssBaseline />
        <nav className={classes.drawer} aria-label="mailbox folders">
          {/* The implementation can be swapped with js to avoid SEO duplication of links. */}
          <Hidden smUp implementation="css">
            <Drawer
              container={container}
              variant="temporary"
              anchor={theme.direction === 'rtl' ? 'right' : 'left'}
              open={mobileOpen}
              onClose={handleDrawerToggle}
              classes={{
                paper: classes.drawerPaper,
              }}
              ModalProps={{
                keepMounted: true, // Better open performance on mobile.
              }}
            >
              {drawer}
            </Drawer>
          </Hidden>
          <Hidden xsDown implementation="css">
            <Drawer
              classes={{
                paper: classes.drawerPaper,
              }}
              variant="permanent"
              open
            >
              {drawer}
            </Drawer>
          </Hidden>
        </nav>
        <main className={classes.content}>
          <div className={classes.toolbar} />
            {renderSwitch(tabTracker)}
          <Link href="#">
            <ControlPointIcon value="newMessage" primary="newMessage" className=        {classes.newMessage} onClick={newMsg} />
          </Link>
        </main>
      </div>
      <Copyright />
    </React.Fragment>
  );
}

// ResponsiveDrawer.propTypes = {
//   /**
//    * Injected by the documentation to work in an iframe.
//    * You won't need it on your project.
//    */
//   window: PropTypes.func,
// };

export default Message;

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    e.target 为您提供实际触发点击的元素,因此当您在ListItem 中有多个元素作为子元素时,您可能点击了ListItemIcon,因此e.targetlistItemIcon这不是你的意图,因为它会给你一个不正确的 e.target.firstChild.data

    因此,您可以使用e.currentTarget,它将为您提供附加 onClick 侦听器的元素,或者您可以使用内联箭头函数简单地将信息传递给 tabControl

    const tabControl = (value) => {
        setTabTracker(value);
    }
    
    const drawer = (
        <div>
          <div className={classes.toolbar} />
          <Divider />
          <List className={classes.listItemStyle}>
            {['Inbox', 'Send email', 'Drafts'].map((text, index) => (
              <ListItem button key={text} onClick={() => tabControl(text)}>
                <ListItemIcon>{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}</ListItemIcon>
                <ListItemText primary={text} />
              </ListItem>
            ))}
          </List>
          <Divider />
          <List>
            {['Trash', 'Spam'].map((text, index) => (
              <ListItem button key={text} onClick={() => tabControl(text)}>
                <ListItemIcon>{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}</ListItemIcon>
                <ListItemText primary={text} />
              </ListItem>
            ))}
          </List>
        </div>
      );
    

    【讨论】:

    • 嗨,Shubham,非常感谢。我将 e.target 更改为 e.currentTarget 并且效果很好
    猜你喜欢
    • 2022-09-24
    • 2021-03-14
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多