OnTouchTap fires twice using the material-ui dialog

We created a React project that uses Material-ui to display dialog boxes. For some reason, when you press a button that launches a dialog to open, a second touch event appears that could potentially trigger a link or button located in a dialog box. A similar problem occurs when you close the dialog box by clicking on the button. In this case, the dialog closes, but causes another touch event for the element that is located immediately after the element that you clicked on.

We have enabled react-tap-event-plugin to use Material-ui, and the application works very well if there are no two elements that overlap this ghost crane behavior.

This is a simplified version of what our component looks like:

 import React, { Component } from 'react' import Dialog from 'material-ui/Dialog' class Introduction extends Component { constructor(props) { super(props) this.state = { complete: false } this.finish = this.finish.bind(this) } finish() { this.setState({ complete: true }) } render() { const actions = ( <div> <button onTouchTap={this.finish}>Finish</button> </div> ) if (!this.state.complete) { return ( <Dialog open actions={actions}> <h3>Dialog header</h3> <p>Dialog text</p> </Dialog> ) } return null } } 

This, when this β€œDone” action button is clicked, closes the dialog and then the element behind it also receives the touchTap event.

If that matters, we use Cordova to port the application to mobile. We encounter this problem only on mobile devices (specifically on iOS), but also on device mode when testing in Chrome.

What am I doing wrong? Any advice would be appreciated.

+5
source share
2 answers

The problem is that after the delay, the onClick event is fired, whether you are handling the onTouchTap event or not. Therefore, after the onTouchTap event is fired and the dialog box is closed, another onClick event appears after the delay in the same place where the onTouchTap event was fired. Thus, any element that is under your touch after the dialogue disappears will receive an onClick event.

To fix this: call e.preventDefault () inside the onTouchTap event handler. Like this:

 <Button onTouchTap={(e) => { e.preventDefault(); this.finish()}}>Finish</Button> 

Hope this helps.

+4
source

When I run my code, I get this error:

 Uncaught TypeError: Cannot read property 'setState' of null 

So this keyword is null. You need to bind your function to an instance of the class. Or in the constructor use:

 constructor(props) { super(props) this.finish = this.finish.bind(this); this.state = { complete: false } } 

or

 <button onTouchTap={this.finish.bind(this}>Finish</button> 

Or you can use the es6 arrow functions, which are automatically associated with the class.

 finish = () => { this.setState({ complete: true }) } 

And I think the same problem occurs when you try to open it with a button.

0
source

All Articles