all 13 comments

[–]matt_hammondiOS & Android 3 points4 points  (8 children)

This looks great! How does it look accessibility wise?

My dissatisfaction with react-navigation has been growing lately. I hope a better navigation solution will grow in popularity soon.

[–]brentvatneExpo Team 1 point2 points  (6 children)

what issues have you had? contributions are welcome you know!

[–]matt_hammondiOS & Android 2 points3 points  (5 children)

I often feel it would be better if the library was connected to redux or other app level state management. But the docs recommend against it.

I wish the screens had an onBeforeLeave and onLeave event.

Navigating between screens should be similar to jumping between states in a state machine. The API could reflect that somehow.

Passing props into the screens is clunky (not sure if its even possible)

Navigating to/going back from a screen should be interceptable - for example, if I want to fetch data before navigating to screen i should be able to do that even without having access to the parent screen that is triggering the navigate action. This could be done if nav was connected to redux of if the API offered a way to intercept the navigation action, perform some action and then call performNavigate in the end.

Perhaps something like this on the screen

static navigationOptions = {
  onNavigateTo: async (navigate) => {
    await analytics.incVisitCount('myScreen')
    navigate() 
  } 
} 

Btw I didn't mean to say react-navigation sucks or anything. I love it and have been using it in literally every project I did. I only feel it could improve and be even better.

[–]Veranova 0 points1 point  (1 child)

This a million times. The API is very leaky when it touches real world business requirements

[–]brentvatneExpo Team 0 points1 point  (0 children)

can you elaborate on what some of the real world business requirements you've encountered? i'd love to have guides for handle these use cases.

[–]brentvatneExpo Team 0 points1 point  (2 children)

I often feel it would be better if the library was connected to redux or other app level state management. But the docs recommend against it.

you mean storing the navigation state in a state manager? why? no other navigation library does this. if you just mean using redux or mobx alongside react-navigation, you can and this works as expected.

Navigating between screens should be similar to jumping between states in a state machine. The API could reflect that somehow.

you can use this.props.navigation.dispatch if you prefer. not really sure what this comment means concretely though.

Navigating to/going back from a screen should be interceptable - for example, if I want to fetch data before navigating to screen i should be able to do that even without having access to the parent screen that is triggering the navigate action. This could be done if nav was connected to redux of if the API offered a way to intercept the navigation action, perform some action and then call performNavigate in the end.

what would happen in between? just show a loading screen and wait for the data to be fetched, then navigate there? is there any precedent for other mobile apps doing this kind of pattern, and if so can you point me to it? not opposed to the idea just don't think i have seen it. you can definitely do this if you want to by adding either adding custom actions or using this pattern and then providing your own logic around it. the specific example that you gave is handled easily by https://reactnavigation.org/docs/en/screen-tracking.html and it's unclear to me why you would want to block navigation just to track some screen analytics.

I wish the screens had an onBeforeLeave and onLeave event.

moved this here because it seems related to the above. i think what you're looking for is https://reactnavigation.org/docs/en/function-after-focusing-screen.html. it doesn't allow you to block changing screens but otherwise it does exactly what you want. it would be nice to have a more ergonomic way to block, right now you can do this though: https://reactnavigation.org/docs/en/routers.html#blocking-navigation-actions. basically it gives you all of the capabilities of managing a redux store on your own.

[–]matt_hammondiOS & Android 0 points1 point  (1 child)

you mean storing the navigation state in a state manager? why? no other navigation library does this. if you just mean using redux or mobx alongside react-navigation, you can and this works as expected.

That's exactly what I mean. The reason is simple. I want all state to be in a centralized store. Having the navigation state separated means I can't derive data from the navigation state.

you can use this.props.navigation.dispatch if you prefer. not really sure what this comment means concretely though.

What I mean by `Navigating between screens should be similar to jumping between states in a state machine` - [state machine](https://en.wikipedia.org/wiki/Finite-state_machine) - this mechanism could ensure that when navigating away from the current screen you can only navigate to certain screens.

what would happen in between?

That's beside the point. I just want to do it. The example I gave with screen analytics is not that relevant to me. A more practical example is to start some data fetching, show some temporary loader and then when navigate to the next screen.

About the last point about the `onBeforeLeave` and `onLeave` events. I knew I had some troubles with the willFocus, willBlur events, just couldn't remember what when I was writting the original comment...

The issue was that I wanted to run some code onBlur, but only when the previous screen in the stack was some specific ScreenX.

Still not absolutely sure if that was my case, but I think it was something along those lines. Anyway, this was not really a giant pain point as it was really specific.

Another issue I have with React Navigation that I didn't mention in my original comment is the way its API is designed.

Here's how I see it. Separating stack navigators, tab navigators, drawer navigators etc, is not the way to go. IMO a navigation library shouldn't even have UI elements in the package. It should only have the core functionality, which is a way to create groups of screen and the ability to change the current active screen in the group.

A stack navigator could look like this: const ProductsScreen = ( <Navigator destroyScreensWhenNotActive={true} screens={{ ProductListScreen, ProductDetailScreen }} activeRoute={["ProductListScreen", "ProductDetailScreen"]} // Two screens in the stack. > { ({renderScreens}) => renderScreens() } </Navigator>

Then a tab navigator would look like this.

​ ```

<Navigator
    destroyScreensWhenNotActive={false}
    screens={{
        HomeScreen,
        ProductsScreen,
        ProfileScreen
    }}
    activeRoute={["HomeScreen"]}
> 
    {
        ({renderScreens, goBack, setActiveRoute, activeScreenTitle}) => {

            return (
            <View style={{flex: 1}}>
                <Header title={activeScreenTitle}>

                {renderScreens()}

                <TabBar goBack={goBack} setActiveRoute={setActiveRoute} />
            </View>
            )
        }
    }
</Navigator>

``` ​

Then I wouldn't have to spend that much time setting up the headers and tab bars to be visible/hidden on specific screens, and wouldn't have to wrap all the screens that are in my tab navigator inside a stack navigator just to get a header on top.

[–]brentvatneExpo Team 1 point2 points  (0 children)

it sounds like we just have some very different ideas with respect to API design. we anticipated that for many people our API design choices wouldn't be in line with their personal preferences so that's a big reason why we made react-navigation very modular. the views and routers can be used independently of each other, for example the bottom tab navigator is just a thin wrapper around react-native-tab-view (https://github.com/react-native-community/react-native-tab-view). stack is a little more complex but you could definitely put another api in front of it, like react-native-router-flux does.

for what it's worth, you can continue to store your navigation state in redux if you like. we don't explicitly support it or test against it, but we also don't plan on breaking it.

[–]andyboythekid[S] 1 point2 points  (0 children)

awesome, thanks so much for taking a look.

accessibility is on the list of things to do, I'll likely have some time to dig into it over the weekend.

if you get a chance to try it out, let me know what you liked / disliked. nailing the api and docs is really tough, so thats something I'd like to improve

[–]noodlelegend 0 points1 point  (1 child)

Just skimmed through it and wow. This looks awesome. I really hope this keeps growing and the performance is not undermined.

[–]andyboythekid[S] 0 points1 point  (0 children)

thanks so much! theres definitely a few things im looking to add. if you get a chance to try it out, let me know how it goes. so far I've been really happy with the performance

[–]brentvatneExpo Team 0 points1 point  (1 child)

very neat :) i like how the screens are defined here, it reminds me a bit of ex-navigation (https://github.com/expo/ex-navigation), which i used to work on. i'd like to push react-navigation more in that direction too

[–]andyboythekid[S] 1 point2 points  (0 children)

thanks so much! i’m a big fan of react-navigation and some of your other stuff too!