Reputation:
I'm trying to do the following I have a dropdown menu where I created state to have only one menu item active at a time and I will also use this to make the active page effect And then I need to do this check on my jsx I move to my menu in all my states I need to check the following:
const { name, link, dropdownItems } = tag;
if my name exists in my visibleMenu
array
and if it is true and I also need to check if my dropdownItems
is true for there yes render my dropdown menu, basically i'm a little confused on how to do these checks in jsx
code:
const MenuBar = props => {
const MenuTags = [
{
name: 'home',
link: '/',
dropdownItems: {
names: ['one', 'two', 'three'],
link: ['/aa', '/b'],
},
},
{
name: 'about',
link: '../abovisibleMenuut',
dropdownItems: {
names: ['one', 'two', 'three'],
link: ['/aa', '/b'],
},
},
{ name: 'not dropdown', link: '../dashboard' },
{ name: 'not dropdown', link: '../dashboard/about' },
];
const [visibleMenu, setVisibleMenu] = useState(
MenuTags.reduce((r, e) => ((r[e.name] = false), r), {}),
),
onUpdateVisibility = item => {
const visibleMenuCopy = { ...visibleMenu };
Object.keys(visibleMenuCopy).forEach(
key => (visibleMenuCopy[key] = key === item),
);
setVisibleMenu(visibleMenuCopy);
};
console.log(visibleMenu);
return (
<>
{MenuTags.map(item => (
<MenuItem
tag={item}
visibleMenu={visibleMenu}
onClick={() => onUpdateVisibility(item)}
/>
))}
</>
);
};
and this is my menu items: ( here i need jsx conditions )
const MenuItem = ({ tag, visibleMenu }) => {
const { name, link, dropdownItems } = tag;
console.log(visibleMenu);
return (
<NavLi>
<Link to={link}>{name}</Link>
</NavLi>
);
};
I don't know if this is the correct logic, but it was the only way I managed to get only one state of my array to be true at a time to render my dropdown menu or apply a css to my active item
Upvotes: 0
Views: 56
Reputation: 1606
Hey I answered you other question didn't know you only wanted one visible menu but, I'll use the code I had yesterday, I still think you should change the way you are managing your visibleMenu. Instead of setting the visible inside the MenuItem class you can set it on the MenuBar
const MenuBar = props => {
const menuTags = [
{ name: 'home', link: '/', dropdownItems: ['one', 'two', 'three'] },
// ... other menu tags you had.
]
const [visibleIndex, setVisibleIndex] = useState(null)
const = handleClick = index => {
if (visibleIndex === index) return setVisibleIndex(null)
return setVisibleIndex(index)
}
return (
<NavUl isOpen={props.isOpen}>
{menuTags.map((menuTag, index) => {
return (
<MenuTag
tag={menuTag}
visibility={index === visibleIndex}
onClick={() => handleClick(index)}
/>
)
})}
<li>
<FontAwesomeIcon
// Move the logic to only be in the Parent, this component shouldn't have to
// pass it's parents variables.
onClick={props.toggleOpen}
// ... the rest of what you had
/>
</li>
</NavUl >
)
}
// Handle visibility through props instead!
const MenuItem = ({ tag, visibility }) => {
const { name, link, dropdownItems } = tag;
return (
<NavLi >
<Link to={link}>{name}</Link>
// If these are true dropdown items will appear.
{visibility && dropdownItem && (
{dropdownItems.map(item => (
<ul>
<li>
<a>{item}</a>
</li>
</ul>
))}
)}
</NavLi>
);
};
Hope that helps and happy coding :)
Upvotes: 1