2017-10-09 47 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

相關問題