React-native: undefined is not an object (evaluating 'this.props.navigator.push')

Created on 28 Mar 2015  ·  21Comments  ·  Source: facebook/react-native

I'm trying to open a second view with a button but I'm receiving: undefined is not an object (evaluating 'this.props.navigator.push') error.

var RegisterNowButton = React.createClass({
  render: function() {
    return (
      <View>
        <TouchableHighlight onPress={this.props.onSelect}>
        <View style={styles.registerNowButtonContainer}>
          <Text style={styles.registerNowButton}>Sign Up Now</Text>
        </View>
        </TouchableHighlight>
      </View>
    );
  }
});
var RegistrationScreen = require('./RegistrationScreen');

var LoginOverlay = React.createClass({

  registerNow: function() {
    this.props.navigator.push({
      title: "hey",
      component: RegistrationScreen,
    });
  },

  render() {
    return (
      <View style={styles.buttonsContainer}>

        < RegisterNowButton
          onSelect={() => registerNow()}
        />
      </View>
    );
  }
});

Crash log:

RCTJSLog> "Error: 
 stack: 
  registerNow                       index.ios.bundle:38452
  <unknown>                         index.ios.bundle:38465
  touchableHandlePress              index.ios.bundle:32219
  _performSideEffectsForTransition  index.ios.bundle:30516
  _receiveSignal                    index.ios.bundle:30440
  touchableHandleResponderRelease   index.ios.bundle:30244
  executeDispatch                   index.ios.bundle:12306
  forEachEventDispatch              index.ios.bundle:12294
  executeDispatchesInOrder          index.ios.bundle:12315
  executeDispatchesAndRelease       index.ios.bundle:11694
  forEachAccumulated                index.ios.bundle:12571
  processEventQueue                 index.ios.bundle:11901
  runEventQueueInBatch              index.ios.bundle:17989
  handleTopLevel                    index.ios.bundle:18015
  _receiveRootNodeIDEvent           index.ios.bundle:17877
  receiveTouches                    index.ios.bundle:17961
  jsCall                            index.ios.bundle:7158
  _callFunction                     index.ios.bundle:7405
  applyWithGuard                    index.ios.bundle:877
  guardReturn                       index.ios.bundle:7207
  callFunctionReturnFlushedQueue    index.ios.bundle:7414
 URL: http://localhost:8081/index.ios.bundle
 line: 38452
 message: undefined is not an object (evaluating 'this.props.navigator.push')"
Locked

Most helpful comment

Let's say you are rendering a LoginOverlay component from some class with an access to navigator prop. You might be able to do this:

<LoginOverlay
      navigator={this.props.navigator}
/>

This should work if my understanding of things is correct. :confused:

All 21 comments

I believe you need to use NavigationIOS to be able to access this.props.navigator. Do you have that somewhere else by any chance? since in the code you showed, there isn't anything of that sort.

Yes I have NaviationIOS on another class. I am modifying the Movies demo so everything works, but as soon as I remove the onSelect listener from the ListView row & set it to the button, it doesn't work.

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  NavigatorIOS,
  StyleSheet,
} = React;

var SearchScreen = require('./MoviesApp');

var MoviesApp = React.createClass({
  render: function() {
    return (
      <NavigatorIOS
        style={styles.container}
        initialRoute={{
          title: 'Movies',
          component: SearchScreen,
        }}
      />
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
});

AppRegistry.registerComponent('hi', () => MoviesApp);

module.exports = MoviesApp;

I'm not sure, but my understanding of NavigatorIOS is: In order for your component to be able to access the prop navigator, you have to push it as a route's component (see that SearchScreen component). Can you check if you push your LoginOverlay as a route?

If by any chance you don't want to push it to the navigator directly, you can probably pass that navigator prop down when you create your LoginOverlay class.

This is my guess haha. I think it would worth trying xD

Yes you are right, if I do module.export the other class it works. Now the question is how could I pass the navigator prop down?

Let's say you are rendering a LoginOverlay component from some class with an access to navigator prop. You might be able to do this:

<LoginOverlay
      navigator={this.props.navigator}
/>

This should work if my understanding of things is correct. :confused:

Yeah, adding the navigator={this.props.navigator} works great. Thank you :smile:

You're welcome! :D

Thanks @igodzp

There is a new feature in Navigator that allows children to access the props.navigator object by calling Navigator.getContext(this). This can be used instead of manually passing the context around through props.

If somebody wants to look at how that works in Navigator and port it to NavigatorIOS, I'd be happy to review it and merge it in!

Where did you insert
navigator={this.props.navigator}
in you code?

@ericvicenti About Navigator.getContext , that's interesting - is there something special I have to do in order to use this feature?

I'm not seeing it...

navigatorgetcontext

Sorry for the thrash. We've removed getContext in recent versions, and we are working on a better implementation.

For now, you can pass the reference to the navigator around using props or context.

OK. I definitely agree a better way then passing it around all the time would be nice.

thank you! It really helped me.

@go1t tnxxx you save my life :)

Has anybody found better way than passing props around ?

我想知道navigator={this.props.navigator}这段代码加到哪里?

加到父组件吧,然后一层一层传?

@Caojunsheng I have encountered the same question. Have you solved it?

@maxiaochaos 我觉得应该是吧

I have solved it in my *.js: add this two lines code:

import NavigationExperimental from 'react-native-deprecated-custom-components';

getDefaultProps(){
return{
navigator: NavigationExperimental.Navigator
};
},

PS: Because Navigator is can't use on my project, so I use NavigationExperimental.Navigator, its work but still have Waring when run project, I dont know why ?

Now, another question is coming: I use the same code as last .js in my another *.js , is show wrong
/// the wrong is: this.props.navigator.push is not a function.

I dont know why???

Now its work, my example code is following :

var RenderNavBar = React.createClass({
getDefaultProps() {
return{
navigator: NavigationExperimental.Navigator
};
},
render() {
return (
.....................

);
},
popToHome(){
this.props.navigator.pop()
},

Then, when you want use this RenderNavBar, you use as < RenderNavBar />, after run is not work, its say : this.props.navigator.pop() is not a function.

So the important is: < RenderNavBar navigator={this.props.navigator} />

// The problem of : this.props.navigator.push is not a function. The way is same.

Now, its working, happyyyyy ;)

Was this page helpful?
0 / 5 - 0 ratings