Custom navigation with Navigator component in React-Native

Kosmetika picture Kosmetika · Mar 30, 2015 · Viewed 25.8k times · Source

I’m exploring possibilities of React Native while developing a demo app with custom navigation between views with the help of Navigator component.

The main app class renders navigator and inside renderScene returns passed component:

class App extends React.Component {
    render() {
        return (
            <Navigator
                initialRoute={{name: 'WelcomeView', component: WelcomeView}}
                configureScene={() => {
                    return Navigator.SceneConfigs.FloatFromRight;
                }}
                renderScene={(route, navigator) => {
                    // count the number of func calls
                    console.log(route, navigator); 

                    if (route.component) {
                        return React.createElement(route.component, { navigator });
                    }
                }}
             />
        );
    }
}

For now app contains two views:

class FeedView extends React.Component {
    render() {
        return (
            <View style={styles.container}>
                <Text>
                    Feed View!
                </Text>
            </View>
        );
    }
}

class WelcomeView extends React.Component {
    onPressFeed() {
        this.props.navigator.push({
            name: 'FeedView',
            component: FeedView
        });
    }

    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>
                    Welcome View!
                </Text>

                <Text onPress={this.onPressFeed.bind(this)}>
                    Go to feed!
                </Text>
            </View>
        );
    }
}

What I want to figure out is:

  • I see in the logs that when pressing “go to feed” renderScene is called several times though the view renders correctly once. Is it how the animation works?

    index.ios.js:57 Object {name: 'WelcomeView', component: function}
    index.ios.js:57 Object {name: 'FeedView', component: function}
    // renders Feed View
    
  • Generally does my approach conform to the React way, or can it be done better?

What I want to achieve is something similar to NavigatorIOS but without the navigation bar (however some views will have their own custom navigation bar).

Answer

Eric Vicenti picture Eric Vicenti · May 2, 2015

Your approach should work great. In big apps at Fb, we avoid calling the require() for the scene component until we render it, which can save a bit of start-up time.

The renderScene function should be called when the scene is first pushed to the Navigator. It will also be called for the active scene when the Navigator gets re-rendered. If you see renderScene get called multiple times after a push, then it is probably a bug.

The navigator is still a work in progress, but if you find any problems with it please file on github and tag me! (@ericvicenti)