4
votes

I am trying to implement deep link to my react native app. The problem is I got an error when I tried open the link when my app is at background The error is

undefined is not an object (evaluating 'this.props')

It works fine if my app is not on background (the app is not running)

My initial route is App showing about 2.5sec splash screen before it redirect to specific route depending if the user is login or not, if the user login then it will redirect to Main route, otherwise to login route.

This my App Route

function mapStateToProps (state) {
  return {
    deviceVersion: state.device.version,
    auth: {
      form: {
        isFetching: state.auth.form.isFetching
      }
    },
    global: state.global,
    search: state.search
  }
}


function mapDispatchToProps (dispatch) {
  return {
    actions: bindActionCreators({ ...authActions, ...deviceActions, ...globalActions, ...searchActions }, dispatch)
  }
}

var reactMixin = require('react-mixin')
import TimerMixin from 'react-timer-mixin'

My componentDidMount function

componentDidMount () {
            this.setTimeout(
                    () => {
                      this.props.actions.getSessionToken()
                      this.props.actions.setHeight(height)
                      this.props.actions.getIp()
                      this.props.actions.getUniqueId()
                      this.props.actions.getLanguage()
                    },
                    2500
                )

Render function

render () {
    return (
      <View style={styles.container}>
        <StatusBar
          backgroundColor="#b33939"
        />
        <View style={{flex:1}}>
        <Header isFetching={this.props.auth.form.isFetching}
          showState={this.props.global.showState}
          currentState={this.props.global.currentState}
          onGetState={this.props.actions.getState}
          onSetState={this.props.actions.setState} />
        </View>

        <View style={{flex:1}}>
          <Text style={styles.summary}>Welcome</Text>
        </View>

      </View>
    )
  }
}

reactMixin(App.prototype, TimerMixin)

export default connect(mapStateToProps, mapDispatchToProps)(App)

When I implement Deeplink I add Linking Listener to my componentDidMount function to handle the url, and I move some actions inside timeout to handleOpenURL function

componentDidMount () {
    Linking.getInitialURL()
            .then(url => this.handleOpenURL({ url }))
            .catch(console.error);

    Linking.addEventListener('url', this.handleOpenURL);
  }

handleOpenURL function looks like this

handleOpenURL(event) {
    console.log('URL', event)

    if(!_.isNull(event.url))
    {
      var url = event.url
      var removeDomain = url.replace("https://www.example.com/", "")
      console.log(removeDomain)
      var lastChar = removeDomain[removeDomain.length -1];
      if(lastChar != '/')
      {
        var data = removeDomain.split("/")
        if(data[0] == 'listing')
        {
          this.props.actions.openListingDetail(data[1], null)
        }
        
      }
    }else{
      this.setTimeout(
            () => {
              this.props.actions.getSessionToken()
              this.props.actions.setHeight(height)
              this.props.actions.getIpAdd()
              this.props.actions.getUniqueId()
              this.props.actions.getLanguage()
            },
            2500
        )
    }
  }

getSessionToken function is to check if the user login. and I am using react router flux

This works fine if the app is not currently running. The Url open listing route correctly. This also works fine if open normally without deep link url. But I got an error when the app is on background, it cant execute this.props.actions.openListingDetail(data[1], null) The error message

undefined is not an object (evaluating 'this.props')

android:launchMode="singleTask"

Any idea Whats wrong ?

1

1 Answers

3
votes

It seems you are passing a method as a static function to addEventListener. You could try this:

componentDidMount () {
  Linking.getInitialURL()
    .then(url => this.handleOpenURL({ url }))
    .catch(console.error);

  Linking.addEventListener('url', () => this.handleOpenURL());
}

Hope this helps.