Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

navigator.pop() doesn't remove the last route #1252

Closed
pukhalski opened this issue May 12, 2015 · 8 comments
Closed

navigator.pop() doesn't remove the last route #1252

pukhalski opened this issue May 12, 2015 · 8 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@pukhalski
Copy link

It makes transition to a previous scene, returns true but doesn't remove the last route in stack.

@brentvatne
Copy link
Collaborator

@pukhalski - please post a minimal example demonstrating the issue 😄

@pukhalski
Copy link
Author

Are you looking for navigator.pop() line of code?) Mkay, honestly I have a pretty much comprehensive usage of navigator within my router module. Anyway, here it goes:

'use strict';

var React = require('react-native');

var Scene1 = require('../scenes/Scene1');
var Scene2 = require('../scenes/Scene2');


var {
  Navigator
} = React;

var Router = React.createClass({
    displayName: 'Router',

    prevState: {},

    getInitialState() {
        return this.states()['sceneState1']();
    },

    go(path, data) {
        var routes = this.navigator.getCurrentRoutes();
        var route = {
            path: path, 
            data: data, 
            index: routes.length
        };

        if (routes[routes.length - 1].path === path) {
            return false;
        }

        this.navigator.push(route);
        return true;
    },

    back() {
        this.navigator.pop();
    },


    states() {
        return {
            scene1: () => {
                return {

                };
            },

            scene2: (route) => {
                return {

                };
            }
        }
    },

    views() {
        return {
            scene1: (route, navigator) => {
                return (<Scene1 router={this} />);
            },
            scene2:  (route, navigator) => {
                return (<Scene2 router={this} />);
            }
        }
    },

    _beforeTransition(route) {
        var path = route.path || '';

        if (typeof this.states()[path] === 'function') {
            this.prevState = this.state;
            this.setState(this.states()[path](route));
        }
    },

    render() {
        return (
            <View style={{flex: 1}}>
                <Navigator
                onWillFocus={this._beforeTransition}
                initialRoute={{index: 0, path: 'scene1'}}
                renderScene={
                    (route, navigator) => {
                        if (!this.navigator) this.navigator = navigator;

                        if (typeof this.views()[route.path] === 'function') {
                            return this.views()[route.path](route, this.navigator);
                        }
                    }
                }
                />
            </View>
        );
    }
});

module.exports = Router;

@pwmckenna
Copy link
Contributor

I can consistently reproduce this as well...here's an app that pushes 4 pages, and offers a back button that pops...it also renders the index and page count so you can see that after popping the list of current routes has not changed.

'use strict';

var React = require('react-native');
var {
    AppRegistry,
    Text,
    Navigator,
    TouchableOpacity
} = React;

var Page = React.createClass({
    render: function () { return null; }
});

var App = React.createClass({
    render: function () {
        return (
            <Navigator
                initialRouteStack={[
                    {
                        name: 'Page 1',
                        component: Page
                    },
                    {
                        name: 'Page 2',
                        component: Page
                    },
                    {
                        name: 'Page 3',
                        component: Page
                    },
                    {
                        name: 'Page 4',
                        component: Page
                    }
                ]}
                configureScene={function () {
                    return Navigator.SceneConfigs.HorizontalSwipeJump;
                }}
                renderScene={function (route, navigator) {
                    return <route.component navigator={navigator} route={route} />
                }}
                navigationBar={
                    <Navigator.NavigationBar routeMapper={{
                        Title: function (route, navigator, index, navbar) {
                            return <Text>{(index + 1) + '/' + navigator.getCurrentRoutes().length}</Text>;
                        },
                        LeftButton: function (route, navigator, index, navbar) {
                            var onPress = function () {
                                navigator.pop();
                            };
                            return <TouchableOpacity onPress={onPress}><Text>Back</Text></TouchableOpacity>;
                        },
                        RightButton: function () {
                            return null;
                        }
                    }}/>
                } />
        );
    }
});

AppRegistry.registerComponent('Text', function () {
    return App;
});

@pwmckenna
Copy link
Contributor

i'm believe this is related to the size of initialRouteStack. no matter how many pushes/pops i do, navigator.getCurrentRoutes().length is never less than the initial length provided...ie, if i provide 4 routes to start, i can push routes, and that will change the length of getCurrentRoutes, and it will correctly pop those off (and update the length of getCurrentRoutes), but no matter how many times i pop, getCurrentRoutes().length never goes below the original count.

Update: This counting issue is independent of the contents of the initialRouteStack contents...if you start with 4 routes, pop them all off, then push on 2 completely different routes...getCurrentRoutes will still return 4 routes.

Update: False alarm on my end. getCurrentRoutes was returning the correct list. I was making an incorrect assumption that Title/LeftButton/RightButton would be called to update the values, but once a scene is on the stack, these aren't updated...hence the working behavior for new routes, but not ones that are already rendered.

@pukhalski
Copy link
Author

@pwmckenna, Am I understanding correctly that the issue is valid and appears not only for me? Because one of my assumptions was that the problem is with my router module itself.

@pwmckenna
Copy link
Contributor

@pukhalski I'm actually not able to repro your issue. My mistake was assuming that the navigation bar would be re-rendered when the view it was tied to was rendered. Ignore my contributions to this thread.

@ericvicenti ericvicenti self-assigned this May 19, 2015
@ericvicenti
Copy link
Contributor

I've replicated this issue. I adding some code that logs the count of the route stack onDidFocus, and I've noticed that after swiping back, the count does not go down. I should be able to fix this today or tonight.

@pukhalski
Copy link
Author

Perfect! Thanks!

@facebook facebook locked as resolved and limited conversation to collaborators May 29, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants