-
Notifications
You must be signed in to change notification settings - Fork 46.4k
-
Notifications
You must be signed in to change notification settings - Fork 46.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
onMouseEnter does not fire on an underlaying element if an element above is removed #13956
Comments
If replicated in pure HTML without React, this behaves completely differently than the React examples above. Pure HTML behaviour seems to match more with my expectations than React's behaviour (with or without circumventing synthetic events). Simplest to see the codesandbox and compare ( |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution. |
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you! |
I'm facing a similar problem. I have a list with elements that represent entities, on hover I want to show actions for these entities, such as a delete action. When I delete an entity, the list moves up to fill the 'gap' that it would have created, placing the cursor on top of the next element, however this does not trigger the As far as I'm aware React does not provide other API's that would allow me to capture an event that the cursor has entered this element when the DOM's element change position instead of the user moving the mouse. I have also tried |
On my website I'm using In my case it would be opening an overlay using a Portal, closing the overlay by either clicking the background or a close button and then opening a tooltip (by using I created a reproducible example of this: https://codesandbox.io/s/sweet-shtern-0dm47, where it's important to load the example as a touch device. If you open the overlay, close the overlay by clicking it and then click the log button it won't log anything on touch devices. After closing the overlay you first have to click another part of the page, before the I'm guessing the |
The Note that the I ran into this when creating React Interactive and replaced |
Same problem. CaseWhen some sibling child re-render, the Reproduce
Image 1. ✅ Work correctly if sibling child doesn't re-render Image 2. ❌ Work incorrectly if sibling child re-render Code backup, if the codesandbox link expires// @ts-nocheck
import React from "react";
const selectStyle = {
padding: "8px 12px",
border: "1px solid"
};
const dropdownStyle = {
padding: "8px 12px",
border: "1px solid tomato"
};
// Example with funciton component
const SelectFC = ({ options, searchable }) => {
const [opened, setOpened] = React.useState(false);
const [selected, setSelected] = React.useState("choose");
const handleClick = React.useCallback(() => {
setOpened(true);
}, []);
const handleOptionClick = React.useCallback((event) => {
console.log("[handleOptionClick]");
setSelected(event.currentTarget.dataset.label);
setOpened(false);
}, []);
const handleOptionHover = React.useCallback(() => {
console.log("[handleOptionHover]");
}, []);
const handleOptionMouseDown = React.useCallback((event) => {
console.log("[handleOptionMouseDown]");
event.preventDefault();
}, []);
const renderOption = React.useCallback(
({ label, value }) => {
return (
<div
key={value}
data-label={label}
onClick={handleOptionClick}
onMouseDown={handleOptionMouseDown}
// ⚠️ Doesn't dispatched if sibling child re-render
onMouseEnter={handleOptionHover}
>
{label}
</div>
);
},
[handleOptionClick, handleOptionHover, handleOptionMouseDown]
);
const dropdownContent = options.map(renderOption);
return (
<div>
<div style={selectStyle}>
{opened && searchable ? (
<input type="text" />
) : (
<div onClick={handleClick}>{selected}</div>
)}
</div>
{opened && <div style={dropdownStyle}>{dropdownContent}</div>}
</div>
);
};
// Example with class component
class SelectClass extends React.Component {
scrollBoxRef = React.createRef();
state = {
opened: false,
selected: "choose"
};
open = () => {
this.setState(() => ({ opened: true }));
};
close = () => {
this.setState(() => ({ opened: false }));
};
handleClick = () => {
this.state.opened ? this.close() : this.open();
};
handleOptionClick = (event) => {
console.log("[handleOptionClick]");
const label = event.currentTarget.dataset.label;
this.setState(() => ({
selected: label
}));
this.close();
};
handleOptionHover = () => {
console.log("[handleOptionHover]");
};
handleOptionMouseDown = (event) => {
console.log("[handleOptionMouseDown]");
event.preventDefault();
};
renderOption = ({ label, value }) => {
return (
<div
key={value}
data-label={label}
onClick={this.handleOptionClick}
onMouseDown={this.handleOptionMouseDown}
// ⚠️ Doesn't dispatched if sibling child re-render
onMouseEnter={this.handleOptionHover}
>
{label}
</div>
);
};
render() {
const { options, searchable } = this.props;
const { opened, selected } = this.state;
const dropdownContent = options.map(this.renderOption);
return (
<div>
<div style={selectStyle}>
{opened && searchable ? (
<input type="text" />
) : (
<div onClick={this.handleClick}>{selected}</div>
)}
</div>
{opened && (
<div ref={this.scrollBoxRef} style={dropdownStyle}>
{dropdownContent}
</div>
)}
</div>
);
}
}
const options = [
{
label: "Apple",
value: "apple"
},
{
label: "Orange",
value: "orange"
},
{
label: "Bannana",
value: "bannana"
}
];
export const App = () => {
const [searchable, setSearchable] = React.useState(true);
return (
<div>
<label>
<input
type="checkbox"
checked={searchable}
onChange={(event) => setSearchable(event.target.checked)}
/>
searchable
</label>
<SelectClass options={options} searchable={searchable} />
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById("root")
); |
same problem here |
Do you want to request a feature or report a bug?
Bug - I did do some searching around the issues to see if there was a similar/dupe, but I could not find one.
What is the current behavior?
With 2 elements overlaying on top of each other, if the upper element gets removed while the cursor is over both elements, mouse enter never fires on the element below. I compared this to native browser events and the issue does not appear to persist there (native browser events appear to fire mouse enter for the underlying div when the overlaying div gets removed).
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.
CodeSandbox Example
I provided a top level boolean constant to switch between using react's synthetic events and the native browser events. In the console I keep track of state updates as console logs. The simple way to test - open the console, mouse over the upper div in a position that is also on top of the lower div, click to remove the upper div, the lower div SHOULD fire mouse enter. It does not with synthetic events, but it does with browser events.
What is the expected behavior?
Expected behavior for me would be if react would fire mouse enter on the underlaying div when the upper div is removed.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
I have not had a chance to test previous versions.
The text was updated successfully, but these errors were encountered: