Skip to content

Commit

Permalink
[EnterLeaveEventPlugin] Fix bug when dealing with unhandled DOM nodes (
Browse files Browse the repository at this point in the history
  • Loading branch information
trueadm authored Oct 3, 2019
1 parent abedf17 commit 26ba38a
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
10 changes: 9 additions & 1 deletion packages/react-dom/src/events/EnterLeaveEventPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ const eventTypes = {
},
};

// We track the lastNativeEvent to ensure that when we encounter
// cases where we process the same nativeEvent multiple times,
// which can happen when have multiple ancestors, that we don't
// duplicate enter
let lastNativeEvent;

const EnterLeaveEventPlugin = {
eventTypes: eventTypes,

Expand Down Expand Up @@ -163,9 +169,11 @@ const EnterLeaveEventPlugin = {

accumulateEnterLeaveDispatches(leave, enter, from, to);

if (isOutEvent && from && nativeEventTarget !== fromNode) {
if (nativeEvent === lastNativeEvent) {
lastNativeEvent = null;
return [leave];
}
lastNativeEvent = nativeEvent;

return [leave, enter];
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,55 @@ describe('EnterLeaveEventPlugin', () => {

ReactDOM.render(<Parent />, container);
});

it('should call mouseEnter when pressing a non tracked React node', done => {
const mockFn = jest.fn();

class Parent extends React.Component {
constructor(props) {
super(props);
this.parentEl = React.createRef();
}

componentDidMount() {
ReactDOM.render(<MouseEnterDetect />, this.parentEl.current);
}

render() {
return <div ref={this.parentEl} />;
}
}

class MouseEnterDetect extends React.Component {
constructor(props) {
super(props);
this.divRef = React.createRef();
this.siblingEl = React.createRef();
}

componentDidMount() {
const attachedNode = document.createElement('div');
this.divRef.current.appendChild(attachedNode);
attachedNode.dispatchEvent(
new MouseEvent('mouseout', {
bubbles: true,
cancelable: true,
relatedTarget: this.siblingEl.current,
}),
);
expect(mockFn.mock.calls.length).toBe(1);
done();
}

render() {
return (
<div ref={this.divRef}>
<div ref={this.siblingEl} onMouseEnter={mockFn} />
</div>
);
}
}

ReactDOM.render(<Parent />, container);
});
});

0 comments on commit 26ba38a

Please sign in to comment.