question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Multiple onMouseEnter calls using HOC and setState()

See original GitHub issue

The exact same code works in React but it’s different in Preact. The onMouseEnter event is called indefinitely when you hover on one of the items (even if you don’t move the mouse anymore). I’d expect it to be called only once when hovering between items but it seems like the setState() is re-calling it every time?

React:

const Tooltip = ({ text }) => <div>{text}</div>;
const hoverable = ComposedComponent => class extends React.Component {

    handleMouseEnter() {
        console.log(this.props, 'mouseenter');
        this.props.onEnter();
    }

    render() {
        return (
            <div onMouseEnter={this.handleMouseEnter.bind(this)}>
                <ComposedComponent/>
            </div>
        );
    }
};

class App extends React.Component {

    constructor(props) {
        super(props)
        this.state = {
            text: 'bla'
        }
    }

    render() {
        const getElements = () => {
            const hoverables = [];
            ['a', 'b', 'c'].forEach((element) => {
                const Hoverable = hoverable(() => <div>{element}</div>);
                hoverables.push(<Hoverable key={element} onEnter={() => this.setState({ text: element })}/>);
            });
            return hoverables;
        }


        return (
            <div>
                <div>
                    {getElements()}
                </div>
                <Tooltip text={this.state.text}/>
            </div>
        );
    }
}

ReactDOM.render(<App/>, document.getElementById('container'));

Preact:

/** @jsx h */
const { h, render, Component } = preact;

const Tooltip = ({ text }) => <div>{text}</div>;
const hoverable = ComposedComponent => class extends Component {

    handleMouseEnter() {
        console.log(this.props, 'mouseenter');
        this.props.onEnter();
    }

    render() {
        return (
            <div onMouseEnter={this.handleMouseEnter.bind(this)}>
                <ComposedComponent/>
            </div>
        );
    }
};

class App extends Component {

    constructor(props) {
        super(props);
        this.state = {
            text: 'bla'
        }
    }

    render() {
        const getElements = () => {
            const hoverables = [];
            ['a', 'b', 'c'].forEach((element) => {
                const Hoverable = hoverable(() => <div>{element}</div>);
                hoverables.push(<Hoverable key={element} onEnter={() => this.setState({ text: element })}/>);
            });

            return hoverables;
        }


        return (
            <div>
                <div>
                    {getElements()}
                </div>
                <Tooltip text={this.state.text}/>
            </div>
        );
    }
}

render(<App/>, document.body);

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
yaodingydcommented, May 31, 2018

React acts “correct” because its synthetic events.

Preact has infinite events because it’s how DOM and native events works, I also created a example with vanilla js: link. Move mouse on text and watch console log.

This is because on mouse enter, old div is removed and new div is created, added same event listener and appended to DOM. Since this is a new node, event listener would trigger, thus the infinite loop. Preact essentially does the same thing.

For react, I would say because of the synthetic events system, react would intercept the following invoke as it might be seen as the same event listener.

I would say this is a “won’t fix” for Preact: no similar event system will be added into Preact in the near future.

0reactions
marvinhagemeistercommented, Jun 1, 2018

@yaodingyd Oh sorry, my bad :S

Read more comments on GitHub >

github_iconTop Results From Across the Web

Multiple onMouseEnter calls using HOC and setState() #1129
The onMouseEnter event is called indefinitely when you hover on one of the items (even if you don't move the mouse anymore). I'd...
Read more >
javascript - How to make an hover state HOC without wraping ...
I'm trying to write a Higher-order Component which provide a hover property to a component. But I can't make it work with any...
Read more >
React onHover Event Handling (with Examples) - Upmostly
There is no onHover event handler in React. Instead, we have the onMouseDown, onMouseLeave, and onMouseEnter events to perform onHover actions in React....
Read more >
HOC Pattern
One way of being able to reuse the same logic in multiple components, is by using the higher order component pattern. This pattern...
Read more >
Introduction to React - CSDN博客
This post demonstrates the concepts of Reactand its general use. The basic operations of React will be demonstrated.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found