carlsednaoui / ouibounce

Increase your landing page conversion rates.
MIT License
2.31k stars 373 forks source link

Can't get disable() working with React #125

Closed eric-burel closed 7 years ago

eric-burel commented 7 years ago

Hi guys,

I am trying to wrap ouibounce into a React component. It works mostly fine (thanks for this great package btw), however I can't unmount cleanly.

Here is how my component works :

However it is not disabled, the callback is still fired when an exit intent is detected eventhough my OnExitModal component is unmounted. This leads to a small (but annoying when I see it 57 times a day) React error message, since I am setting state of an unmounted component.

Any React user there with an idea :) ?

Here is the complete code :

/**
 * A modal that opens on exit intent, using Ouibounce
 */
 //@see https://github.com/carlsednaoui/ouibounce

import React, { Component, PropTypes } from 'react'
import Dialog from 'material-ui/Dialog'
import ouibounce from 'ouibounce'

export default class OnExitModal extends Component{
  constructor(props){
    super(props)
    this.state ={
      open : false,
      handler:null,
    }
    this.handleClose = this.handleClose.bind(this)
  }
  handleClose(){
    this.setState({open:false})
    // we set the modal again, so that it reopens when we quit next time
    this.setupOuibounce()
  }

  setupOuibounce(){
    // we actually don't need the document.getElementById, as we open the
    // modal manually using the callback
    return ouibounce(document.getElementById('ouibounce-modal'),{
      aggressive:true, // appears every time
      sensitivity: 100,
      callback:()=>{ this.setState({open:true})} // open the modal
    })
  }

  componentDidMount(){
    const handler = this.setupOuibounce()
    this.setState({handler})
  }
  componentWillUnmount(){
    // disable the ouibounce on unmount
    if (this.state.handler) this.state.handler.disable()
  }

  render(){
    return(
    <Dialog id="ouibounce-modal"
      autoScrollBodyContent={true}
      contentStyle={this.props.style}
      open={this.state.open}
      onRequestClose={this.handleClose}
      >
      {this.props.children}
    </Dialog>
  )
  }
}
OnExitModal.propTypes = {
  children : PropTypes.node.isRequired,
  style: PropTypes.object,
}
tikotzky commented 7 years ago

Looks like the issue may be that you aren't saving the handler again in handleClose()

try changing it to something like

handleClose(){
    // we set the modal again, so that it reopens when we quit next time
    const handler = this.setupOuibounce()
    this.setState({open:false, handler})
  }
eric-burel commented 7 years ago

Definitely the right solution, thanks. I should have posted on stackoverflow first. I'll try to publish a React version of ouibounce some day.