React-Bootstrap Open dropdowns menu when hovering
First error: onMouseEnter
and onMouseLeave
expected a function declaration instead of a call, because you call handleOpen(index)
, it re-render, then re-render again, and so on ...
to fix the error:
onMouseEnter={(e) => handleOpen(index)}
Second error:
<NavDropdown.Item href={element.url} key={element.id} onClick={handleClose}>
this will call handleClose with an event, expected the index
, to fix:
onClick={e => handleClose(index) }
Third error: your handleClose and handleOpen is updating the state with the reference to the old state, expected a new array, to fix:
const handleOpen = index => {
let temp = [...isOpen];
temp[index] = true;
setIsOpen(temp);
};
const handleClose = index => {
let temp = [...isOpen];
temp[index] = false;
setIsOpen(temp);
};
Also, your isOpen
name is ambiguous, and wrong initialization too!
const [isOpen, setIsOpen] = useState(() => {
return Array.apply(null, Array(MENU.length)).map(x => false);
});
should be
const [status, setStatus] = useState(MENU.map(x=> false));
Overall you can write like this:
const updateStatus = (value, index) => {
const clone = [...status];
clone[index] = value;
setStatus(clone);
}
<NavDropdown
onMouseEnter={e => updateStatus(true, index)}
onMouseLeave={e => updateStatus(false, index)}
show={status[index]}
title={item.title}
id={item.id}
key={item.id}
>
{item.sub.map(element =>
<NavDropdown.Item
href={element.url}
key={element.id}
onClick={e => updateStatus(false, index)}
>
{element.item}
</NavDropdown.Item>
)}
</NavDropdown>
React-Bootstrap dropdown on hover
const [show, setShow] = useState(false);
const showDropdown = (e)=>{
setShow(!show);
}
const hideDropdown = e => {
setShow(false);
}
<NavDropdown title="Dropdown"
id="collasible-nav-dropdown"
show={show}
onMouseEnter={showDropdown}
onMouseLeave={hideDropdown}
>
I Have Used This For Open Dropdown Menu On Hover in React Bootstrap.
Loading react-bootstrap's Dropdown data on mouse hover than on mouse click in React functional component?
You should refactor your functional component like this:
function Navigation() {
const [shouldOpen, show] = useState(false);
return (
<NavDropdown
title="About"
onMouseEnter = { () => show(true) }
onMouseLeave = { () => show(false) }
show={ this.shouldOpen }>
<NavDropdown.Item href="#action/1.1">Who we are</NavDropdown.Item>
<NavDropdown.Item href="#action/2.2">
How we work
</NavDropdown.Item>
<NavDropdown.Item href="#action/2.2">
Certifications
</NavDropdown.Item>
</NavDropdown>
)
}
Bootstrap dropdown on hover
Ok, so after a lot of reading boostrap docs, seeing what changes on the code when I click de dropdown and Jquery coding I make it work, this is what I did:
So first I notice that when you click the dropdown this change in the html:
- The
a
element that is inside theli
with classdropdown
has the classshow
and thearia-expanded
is changed to true. - The
div
with classdropdown-menu
that is also indise theli
with classdropdown
has the classshown
and theattribute
data-bs-popper = none
is added.
So with this in mind I made 2 functions to get the class dropdown
and watch when the mouse hover this element, so when the mouse enter I add the classes and the attribute, when the mouse leaves I remove the classes and attribute, and this is what it looks like:
$('.dropdown').on("mouseenter", () => {
$(".dropdown > a").addClass('show')
$(".dropdown > a").attr("aria-expanded","true");
$(".dropdown > div").attr("data-bs-popper","none");
$(".dropdown > div").addClass('show')
})
$('.dropdown').on("mouseleave", () => {
$(".dropdown > a").removeClass('show')
$(".dropdown > a").attr("aria-expanded","false");
$(".dropdown > div").removeAttr("data-bs-popper","none");
$(".dropdown > div").removeClass('show')
})
As you can see I use the class dropdown
and select the a
and div
elements that are inside this li
and add or remove the classes and attribute, this is the simple code:
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="drop" role="button" data-bs-toggle="dropdown" aria-expanded="false">Temas</a>
<div class="dropdown-menu" aria-labelledby="drop">
<a class="dropdown-item" href="../default/">Default</a>
<a class="dropdown-item" href="../united/">United</a>
<a class="dropdown-item" href="../yeti/">Yeti</a>
</div>
</li>
And finally in the CSS I add margin-top: -1vh
so the dropdown menu is open when the mouse moves to the element, so the final css is this:
.dropdown:hover .dropdown-menu {
display: flex;
flex-wrap: wrap;
}
.dropdown-menu.show {
margin-top: -1vh;
width: 40%;
margin-left: 38vw;
}
.dropdown-item {
width: 25% !important;
}
Trigger only one dropdown menu on button mouse hover
Methods onMouseEnter
and onMouseLeave
of the Navbar
component change only one state – dropdown
.
You need to add different states and methods for show/hide dropdown-components.
Related Topics
Detect Browser Graphics Performance
Update Progressbar in Each Loop
Jquery Tablesorter CSS Arrow Icons
Prevent Scroll Bounce for the Body Element, But Keep It for Child Elements in iOS
Fixing Sub-Pixel Rounding Issue in a CSS Fluid Grid
Detecting Width: Auto in Jquery
How to Get New Image Size Dimension After Giving Object-Fit:Contain Property to the Image Tag
Cannot Return CSS Property of HTML Element
Why Do Arabic Characters Behave as Separate Characters When Styling Single Arabic Character
Jquery $('#Div').Show().Delay(5000).Hide(); Doesn't Work
Window.Scrollto Not Working in Phonegap - Alternative Solution or Workaround
Write Custom Text on Image Canvas with Fabric.Js and HTML5