2017-10-09 46 views
0

我已经建立了一个包含图标的侧面菜单,点击每个图标后,一个菜单会滑出相应的项目。通过使用点击相同的项目关闭菜单,但不同的项目保持菜单打开

const handleCloseWhenOpen = menuOpen ? { onClick: this.closeMenu } : null; 

然后把

{...handleCloseWhenOpen} 

为道具......这使得它如此,当我点击ICON1菜单打开,并再次点击ICON1时,菜单关闭。如果我点击icon1,菜单打开,然后点击icon2,而不是只是切换菜单数据,菜单关闭,我必须再次点击icon2才能得到menu2的数据。我只是想要菜单关闭时,相同的图标被点击打开它,再次点击。

任何帮助都会很棒。

export default class SidebarNav extends Component { 
 
    static propTypes = { 
 
    children: PropTypes.any, 
 
    }; 
 
    constructor() { 
 
    super(); 
 
    this.state = { 
 
     menuOpen: false, 
 
     sideBarItems: new List(), 
 
     isSelected: false, 
 
    }; 
 
    } 
 

 
    openMenu = (value) => { 
 
    let menuData = []; 
 
    switch (value) { 
 
     case 'icon1': 
 
     menuData = Data.icon1Data; 
 
     break; 
 
     case 'icon2': 
 
     menuData = Data.icon2Data; 
 
    } 
 
    this.setState({ 
 
     menuOpen: true, 
 
     sideBarItems: menuData, 
 
     selectedIcon: value, 
 
    }); 
 
    } 
 

 
    closeMenu = (value) => { 
 
    this.setState({ 
 
     menuOpen: false, 
 
     selectedIcon: value, 
 
    }); 
 
    } 
 

 
    render() { 
 
    const { 
 
      menuOpen, 
 
      sideBarItems, 
 
      selectedIcon, 
 
      } = this.state; 
 
    const { children } = this.props; 
 
    const handleCloseWhenOpen = menuOpen ? { onClick: this.closeMenu } : null; 
 
    return (
 
    <PageWrapper> 
 
     <SideNav 
 
     onClick={this.openMenu} 
 
     selectedIcon={selectedIcon} 
 
     /> 
 
     <PageContentWrapper> 
 
     <Sidebar.Pushable as={Segment}> 
 
      <PushMenu 
 
      visible={menuOpen} 
 
      sideBarItems={sideBarItems} 
 
      {...handleCloseWhenOpen} 
 
      /> 
 
      <Sidebar.Pusher {...handleCloseWhenOpen}> 
 
      {children} 
 
      </Sidebar.Pusher> 
 
     </Sidebar.Pushable> 
 
     </PageContentWrapper> 
 
    </PageWrapper> 
 
    ); 
 
    } 
 
}

export default class SideNav extends Component { 
 
    static propTypes = { 
 
    onClick: PropTypes.func, 
 
    selectedIcon: PropTypes.any, 
 
    } 
 
    render() { 
 
    const { 
 
      onClick, 
 
      selectedIcon, 
 
      } = this.props; 
 
    return (
 
    <SideBarDiv> 
 
     <IconList> 
 
     { 
 
      Data.icon1Data.map((item, itemIndex) => { 
 
      return (
 
       <IconWrapper 
 
       key={itemIndex} 
 
       className={ 
 
       selectedIcon === item.get('value') 
 
       ? 'Icon-pressed-shadow' 
 
       : 'Icon-right-shadow' 
 
       } 
 
       onClick={() => onClick(item.get('value'))} 
 
       > 
 
        <ListItem> 
 
        <Icon name={item.get('name')} /> 
 
         </ListItem> 
 
       </IconWrapper> 
 
      ); 
 
      }) 
 
     } 
 
     { 
 
      Data.icon2Data.map((item, itemIndex) => { 
 
      return (
 
       <IconWrapper 
 
       key={itemIndex} 
 
       className={ 
 
       selectedIcon === item.get('value') 
 
       ? 'Icon-pressed-shadow' 
 
       : 'Icon-right-shadow' 
 
       } 
 
       onClick={() => onClick(item.get('value'))} 
 
       > 
 
       <ListItem> 
 
        <Icon name={item.get('name')} /> 
 
        <NotificationLabel>3</NotificationLabel> 
 
       </ListItem> 
 
       </IconWrapper> 
 
      ); 
 
      }) 
 
     } 
 
     </IconList> 
 
    </SideBarDiv> 
 
    ); 
 
    } 
 
}

export default class PushMenu extends Component { 
 
    constructor() { 
 
    super(); 
 
    this.state = { 
 
     visible: false, 
 
    }; 
 
    } 
 
    static propTypes = { 
 
    visible: PropTypes.bool, 
 
    sideBarItems: PropTypes.instanceOf(Immutable.List), 
 
    } 
 
    render() { 
 
    const { 
 
      sideBarItems, 
 
      visible, 
 
      } = this.props; 
 
    return (
 
     <Sidebar 
 
     className='Push-menu' 
 
     animation='push' 
 
     width='thin' 
 
     visible={visible} 
 
     > 
 
     <div> 
 
      { 
 
      sideBarItems ? sideBarItems.map((menuTitle, menuTitleIndex) => { 
 
       return (
 
       <div key={menuTitleIndex}> 
 
       <Header>{menuTitle.get('title')}</Header> 
 
       <Linebreak /> 
 
       </div> 
 
      ); 
 
      }) 
 
      : <Header>Content</Header> 
 
      } 
 
     </div> 
 
     <List> 
 
      { 
 
      sideBarItems ? sideBarItems.map((menuItem, menuItemindex) => { 
 
       return (
 
       <li key={menuItemindex}> 
 
        { 
 
        !!menuItem.get('childItems') && 
 
        menuItem.get('childItems').map((childItem) => { 
 
         return (
 
         <div key={childItem.get('name')}> 
 
          <ListItemHeader>{childItem.get('name')}</ListItemHeader> 
 
          <List> 
 
          { 
 
           childItem.get('nestedItems').map((nestedItem) => { 
 
           return (
 
            <ListLink key={nestedItem.get('name')}> 
 
            <Link 
 
             activeStyle={{ fontWeight: 'bold' }} 
 
             to={nestedItem.get('route')} 
 
            > 
 
             <li>{nestedItem.get('name')}</li> 
 
            </Link> 
 
           </ListLink> 
 
           ); 
 
           }) 
 
          } 
 
          </List> 
 
         </div> 
 
        ); 
 
        }) 
 
        } 
 
       </li> 
 
      ); 
 
      }) 
 
      : null 
 
      } 
 
     </List> 
 
      </Sidebar> 
 
    ); 
 
    } 
 
}

回答

1

SidebarNav的状态具有跟踪任何菜单是否打开的字段menuOpen。这是您运行时检查的内容handleCloseWhenOpen。 因此,当您单击Icon1时,menuOpen设置为true。接下来,当您点击Icon2时,menuOpen被检查并发现为真,并切换为false。因此,单击Icon2将关闭Icon1的菜单,而不是打开Icon2的菜单。

你需要做的改正这种行为是分别跟踪每个图标菜单的状态。因此,如果您想跟踪SidebarNav中的状态,则可以在每个图标的状态对象中包含一个字段,例如,

this.state={ 
    ..... 
    menu1Open:false, 
    menu2Open:false, 
    ..... 
} 

然后检查您需要切换哪个字段,具体取决于点击的图标;并相应地呈现菜单。

如果您认为这会变得复杂,您可以让每个SideNav跟踪其自己的状态,将菜单数据作为道具传递给图标,并让点击操作切换菜单的打开和关闭。

+0

你是指“每个图标的字段”是什么意思?像道具? – StuffedPoblano

+0

这很有道理。谢谢。这是答案。我很感激。 – StuffedPoblano

+0

如果我认为它会变得混乱,我认为这会因为有12个图标/菜单而变得混乱......第二个选择是让SideNav追踪它自己的状态。所以我只是在SideNav组件中的构造函数正确吗?我编辑了原始帖子以包含PushMenu组件。 – StuffedPoblano

相关问题