Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native - Navigator Recursive Children Crashes

I am having a look at navigator component in React-Native but cannot get it to accept a child node that is already in the stack. E.g. if we take the facebook app for example. A user could search for a user, then click friends, then click another user. This crashes when I try to add it to the stack with the error

Invariant Violation: Expected a component class, got [object Object].

I have tried this via the standard navigator and currently the React-Native-Router. My current code looks like this

class OptionsBranch extends Component {
    render() {
        /*<TouchableHighlight style={styles.spaceOut} onPress={() => {this.props.toRoute({name:"test", component:UserProfile})}}><Text>[push]</Text></TouchableHighlight>*/
        return (
            <View style={styles.container}>
                <Text>[OptionsScreen]</Text>
                <TouchableHighlight style={styles.spaceOut} onPress={() => {this.props.toRoute({id:"x", name:"test", component:UserProfile})}}><Text>[push]</Text></TouchableHighlight>
                <TouchableHighlight style={styles.spaceOut} onPress={() => {this.props.toBack()}}><Text>[pop]</Text></TouchableHighlight>
            </View>
        );
    }
}

I can get this to work indefinitely so long as I never re-use a class. The moment I do, I get the error.

I would post links to research but there isn't much out there for Navigator (Rather than NavigatorIOS) except for the samples included with the Framework and they seem to achieve ti but without passing a full route, which i would need.

e.g.

<NavButton onPress={() => { navigator.push(_getRandomRoute()) }} text="Push"/>

If I try to use this in my code (without React-Native-Router) i.e.

<TouchableHighlight onPress={() => { this.props.navigator.push({ name:"myComponent", component:myComponent }) }} />

it errors also.

Why is this? Is this a limitation of Navigator? Is it an error in my code?

A Boiler plate app that uses a TabBar and Navigator could have been quite helpful to learn from. NavigatorIOS is a little limited for customisation.

like image 912
Moss Palmer Avatar asked May 14 '15 16:05

Moss Palmer


1 Answers

It appears my error was to do with a cyclic dependency.

To prevent it I LazyLoaded the classes that I needed to populate the Navigator. Instead of blanket "requiring" them all at the top of the js files (yes, ignore all those tutorials you've done). Instead require them in the functions that will use them. This remove the cyclic dependancy and allows you to reuse the classes.

e.g. instead of this:

var myClass = require('./MyClass');
...
(some other code)
...
render: function(){
    return(
        <TouchableHighlight onPress={ () => {this.props.toRoute( {name: "myPage", component: myClass, data: "SomeData" } )}>
            <Text>Link</Text>
        </TouchableHighlight>
    );
}

do this:

goToMyRoute: function(myParameter){
    var myClass = require('./MyClass');
    this.props.toRoute( {name: "myPage", component: myClass, data: myParameter })
}

render: function(){
    return(
        <TouchableHighlight onPress={ () => {this.goToMyRoute("SomeData")} }>
            <Text>Link</Text>
        </TouchableHighlight>
    );
}
like image 186
Moss Palmer Avatar answered Oct 25 '22 13:10

Moss Palmer