7

For a legacy app we are rewriting parts of web app with React piece by piece. Because of this can't remove junks of document listeners completely. There are lots of different components all over the page that have listeners on them. This is effecting react components performance.

For example; Material UI Toggle Menu, https://codesandbox.io/s/o9970jm69 Toggling menu is fast and responsive to your clicks in example. But for our web app because of these document event listeners, toggle behavior is not the same as the demo.

Is it possible to remove these document click listeners for React elements?

Or is there a way to get rid of from these listener for React components?

Erdal SATIK
  • 652
  • 2
  • 9
  • 32
  • structure your react HTML/JSX the way so that your existing listeners dont target them, unless you have like a global listener for eg listener that targets `a` tag across the page them you are better off making changes in your legacy to modify selector to be specific. – Rikin Dec 23 '18 at 21:36
  • Thank you but there isn't any general targeting document on event listener. All of them have specific targets with ids and classes. But still it is affecting. When i remove event listeners from browser console, everything works fine. – Erdal SATIK Dec 25 '18 at 05:00
  • 2
    what is happening inside the listeners? are they responsible for doing alot of work that is choking the thread? could you provide an example of one of your document listeners? – Ja Superior Dec 27 '18 at 22:15
  • 2
    Is there a gif/minimal reproduction that I can play with? – Brian Le Dec 28 '18 at 04:59
  • Can you add some sort of demo from which we can check it in action? – Just code Dec 28 '18 at 10:38
  • yes, i'll add in a few hours. thanks for responses. – Erdal SATIK Dec 28 '18 at 11:11
  • @ErdalSATIK Why not just run the jQuery "off" function on all your react elements at mount ? http://jqapi.com/#p=off You could even create a HOC to do it in one place. – Tmb Jan 03 '19 at 14:43

4 Answers4

3

Solution #1 for jQuery events

You can use unbind to remove events. If you need know the event name or type, you can see with Chrome Dev Tools

Solution #2 Javascript events

Another method is capture the event and stop the propagation. You can use removeEventListener or set null the property event.

Mosè Raguzzini
  • 15,399
  • 1
  • 31
  • 43
1

instead of trying to remove listeners, I suggest you don't attach them in the first place.

... can't remove junks of document listeners completely

since that is not an option, your second best bet is to modify the listeners so that they exit early if event.target is part of react app (you can verify that by doing document.getElementById('#your-react-dom-root').contains(event.listener))

zhirzh
  • 3,273
  • 3
  • 25
  • 30
1

There are lots of document on click event listeners

You must mean "There are lots of different components all over the page that have listeners on them."

In that case, there are a couple ideas here that may be helpful: Intercept all document link clicks

John Fantastico
  • 332
  • 1
  • 7
1

It has to be a temporary solution (remove it after your rewrite has ended), because it is quite dirty, but you can just run the jQuery off function on your React Element at mount.

To make it easier to use (and to remove), you can also create a HOC to do it in one place, something like that :

function withJqueryOffEvent(WrappedComponent, event) {
    return class extends React.Component {
        componentDidMount() {
            $(this.el).off(event);
        }

        render() {
            return <WrappedComponent ref={el => this.el = el} {...this.props} />;
        }
    };
}

// use it like any other HOC
withJqueryOffEvent(AnyComponent, 'click');

Here, we just create a basic HOC which accept an event name, attach a ref to the wrapped component in the render, and use this ref in a jquery selector after the mount to do the off.

Tmb
  • 450
  • 12
  • 20