admin管理员组

文章数量:1292801

Hello I have doubts on how I can do this in react using useState, basically i have this menu where i need to map, i basically need a state containing all tags, and with boolean state true or false to know if the current item is active, and i will make it active by clicking on the item, and deactivate it when another item is clicked

that is, only one menu item active at a time

export const SideBarTags = [
  {
    name: 'Tutoriais',
    link: '../tutorials',
    icon: faFileAlt,
    dropdownItems: null,
    active: false,
  },
  {
    name: 'Avisos',
    link: '../news',
    icon: faNewspaper,
    dropdownItems: null,
    active: false,
  },
  {
    name: 'Serviços',
    link: '../services',
    icon: faMeteor,
    active: false,
    dropdownItems: [
      { name: 'Elo Boost', link: '/eloBost' },
      { name: 'Duo Boost', link: '/duoBoost' },
      { name: 'MD10', link: '/eloBost' },
      { name: 'Coaching', link: '/duoBoost' },
      { name: 'Vitóriais', link: '/duoBoost' },
    ],
  },
  {
    name: 'Carteira',
    link: '../cartcredit',
    icon: faWallet,
    active: false,
    dropdownItems: [
      { name: 'Histórico', link: '/history' },
      { name: 'Adicionar Crédito', link: '/add' },
    ],
  },
];

and my TSX:

const MenuTags: React.FC<Hamburguer> = ({ isOpen }) => {
    const [menuTags, setMenuTags] = useState(SideBarTags.map());

  return (
    <DashMenu open={isOpen}>
    <MenuItem /> //(this is my tag <li>
    </DashMenu>
  );
};



const MenuItem: React.FC = () => {


  return (
    <ListItem>
      <ListWrap

      >
        <a>
          <FontAwesomeIcon
            className="icon-li"
            icon={icon}
            size={isOpen ? 'lg' : 'lg'}
            fixedWidth
            color="white"
          />
          <span
            className="li-name"
          >
            {name}
          </span>
        </a>
    </ListItem>
  );
};

Hello I have doubts on how I can do this in react using useState, basically i have this menu where i need to map, i basically need a state containing all tags, and with boolean state true or false to know if the current item is active, and i will make it active by clicking on the item, and deactivate it when another item is clicked

that is, only one menu item active at a time

export const SideBarTags = [
  {
    name: 'Tutoriais',
    link: '../tutorials',
    icon: faFileAlt,
    dropdownItems: null,
    active: false,
  },
  {
    name: 'Avisos',
    link: '../news',
    icon: faNewspaper,
    dropdownItems: null,
    active: false,
  },
  {
    name: 'Serviços',
    link: '../services',
    icon: faMeteor,
    active: false,
    dropdownItems: [
      { name: 'Elo Boost', link: '/eloBost' },
      { name: 'Duo Boost', link: '/duoBoost' },
      { name: 'MD10', link: '/eloBost' },
      { name: 'Coaching', link: '/duoBoost' },
      { name: 'Vitóriais', link: '/duoBoost' },
    ],
  },
  {
    name: 'Carteira',
    link: '../cartcredit',
    icon: faWallet,
    active: false,
    dropdownItems: [
      { name: 'Histórico', link: '/history' },
      { name: 'Adicionar Crédito', link: '/add' },
    ],
  },
];

and my TSX:

const MenuTags: React.FC<Hamburguer> = ({ isOpen }) => {
    const [menuTags, setMenuTags] = useState(SideBarTags.map());

  return (
    <DashMenu open={isOpen}>
    <MenuItem /> //(this is my tag <li>
    </DashMenu>
  );
};



const MenuItem: React.FC = () => {


  return (
    <ListItem>
      <ListWrap

      >
        <a>
          <FontAwesomeIcon
            className="icon-li"
            icon={icon}
            size={isOpen ? 'lg' : 'lg'}
            fixedWidth
            color="white"
          />
          <span
            className="li-name"
          >
            {name}
          </span>
        </a>
    </ListItem>
  );
};
Share Improve this question edited Apr 29, 2020 at 23:49 gabriel asked Apr 29, 2020 at 23:23 gabriel gabriel 5003 gold badges11 silver badges23 bronze badges 16
  • You might be better using useReducer for more plex state - reactjs/docs/hooks-reference.html#usereducer – Jon B Commented Apr 29, 2020 at 23:29
  • Where is your react code showing what you tried so far? – MonteCristo Commented Apr 29, 2020 at 23:30
  • 1 No, just in whatever ponent is rendering the menu items you have a piece of state that simply maintains what menu item is active. If this was a flat array you could use the index, for example. Having nested items that aren't all using the same nesting means you have to switch to more of "global" identifier, just something unique in the entire set of menu items. If you provide an example of your menu rendering then I can perhaps amend with my suggestion how to maintain an active item. – Drew Reese Commented Apr 29, 2020 at 23:48
  • 1 Though now I see you do have a fairly flat structure of the main items that you want to toggle active/inactive. A simple mapping could achieve this but IMO it is easier to just maintain what is active separately and skipping the array mappings altogether. – Drew Reese Commented Apr 30, 2020 at 0:05
  • 1 @Drew Reese yes i go use react-router-dom but I'm using active more for my dropdown items, ie I will only have one <ul> dropdown open at a time – gabriel Commented Apr 30, 2020 at 0:23
 |  Show 11 more ments

2 Answers 2

Reset to default 4

Component logic if you wanted to map the menu items with the active item

const [menuItems, setMenuItems] = useState(SideBarTags);

const clickHandler = name => () => {
  setMenuItems(items =>
    items.map(item => ({
      ...item,
      active: item.name === name
    }))
  );
};

...

{menuItems.map(item => (
  <li
    key={item.name}
    className={item.active ? "active" : ""}
    onClick={clickHandler(item.name)}
  >
    {item.name}
  </li>
))}

CSS

.active {
  // could be whatever style you need
  color: red;
}

Super simplified version of what I did in a past project:

const MenuTags = () => {
  const [selectedLink, setSelectedLink] = useState(null)

  return (
    <ul>
      {SideBarTags.map((obj) => (
        <li className={`${selectedLink === obj.name ? 'link--selected' : ''}`}>
          <a
            onClick={() => {
              setSelectedLink(obj.name)
            }}
            href={obj.link}
          >
            {obj.name}
          </a>
        </li>
      ))}
    </ul>
  )
}

Use CSS to open and close the menu items, by having a class such as 'link--selected' added to an element you can just show that item.

本文标签: javascriptReactJs useState Array MapStack Overflow