Is it an acceptable structure to nest Navigator components? - react-native

I have a mobile app where the flow is basically this:
User loads app, is presented with a login/OAuth screen
There are other scenes in the stack that could be pushed on top of this (sign up, forgot password, etc) - related scenes
No TabBarIOS at this point
Once the user authenticates, they're taken to a totally different screen that has a TabBarIOS at the bottom to switch between (for example) messages, settings, news, etc. If on the news tab (listing of news item) and the user taps a news item to view the article, the detail view is pushed onto the stack but the TabBarIOS remains visible.
So I have one main Navigator at the root level to swap between the login/signup stack, and the "user is logged in" stack, and then I have another Navigator within that so the user can navigate around in the news articles.
I'm just wondering if this is a bad pattern in React Native and if there's a better way, or if this is spot on.

Related

How to use React Navigation with endless routes?

I have an app where users can navigate almost endlessly to new screens (I'm using Stack Navigator). There are about 15 different screens, but every screen can be opened with a huge number of different IDs (showing data for different companies, etc). For example in the Company route, the user can open many different Person screens based on employees, and again from Person screens the user can navigate to many different screens, so the navigation is basically endless.
Because React Navigation keeps all screens in memory, after navigating maybe 20-30 different screens, the app becomes very laggy. And because the number of routes is basically endless, it's impossible to keep all screens in memory.
I end up replacing the screen (navigation.replace) instead of pushing it when the user navigates to a new screen. That way there is only one screen in the memory at a time. I also made an array where I push the name and parameters of the new route every time, so when user goes back, I get the previous routes from that array and I replace current screen with the screen from that history array. It works fine, but of course, going back is not as fast as using React Navigation in the standard way.
So the first question: what is the most efficient and CORRECT way of using React Navigation in my case?
Second question: because I have just one screen on React Navigation's history, the swipe back does not work on iOS. Is there an easy way to change swipe back to call my own back function instead of React Navigation's default back?

React native container subpages navigation

I am creating a React native application with the following scenario:
There is a navigation bar at the bottom of the screen, allowing the user to navigate between three main pages. On one of these pages, there is a backdrop with a container overlayed on it with two buttons. Each of these buttons should show open different "pages" in that container, and the navigation bar will be hidden when the user opens one of those "pages". An image is included below.
App layout example
My question is: how is this best implemented in react native?
My original idea was to implement a custom Stack Navigator with createStackNavigator. While this does work, I was wondering if this is a good way to go about it.
One result from using a custom navigator is that the navigation state in the container is also bound to the back button of the device (on Android). However, this is a welcome feature in this case as it makes sense in the navigation flow.

React Navigation same screen in different navigators

TL;DR version : Regarding navigation, how does one handle having the same screen in multiple different navigators ?
Long version :
I have a quite complex app made in React Native app, using React Navigation (social network type), with multiple nested navigators, depending on what the user is doing (registering, login, loading, using the app). The app basicaly allows you to share your experience in various places (who you are with, what you're drinking, etc). Those places have a dedicated profile screen that you can access.
When logged in, I have a bottom tab navigator that leads to the four main sections of the app : feed, post new content, search, user profile.
Each of those sections have a specific stack navigator.
My issue is that some screens can be accessed in multiples sections. I'll take a specific example but it applies to many screens. So, the "Place profile" screen can be accessed through the feed when you click on the place name, from the
search, when you search places, or from the user profile (because we list the user posts, and those posts can have a place mentionned).
I first tried to say that it belongs to the feed navigator and everytime a place is clicked, we move back to the feed tab and to the place screen. It works fine until I click on the "related places" link that opens the map in the search section. The back button (that use navigation.goBack()) goes back in the search stack instead of the global navigation history.
I then tried to add every potential screens to every needing section navigators. Back button is working fine, but I'm having navigation issues now when trying to go to a screen that belongs only to a specific navigator. For those, I then specified the "owner" of it (using navigation.navigate("Foo", { screen: "Bar", params: { baz: buz }})), but I'm having weird navigations results where the navigator state is preserved between tab navigations, despite using unmountOnBlur. Also, that solution is ugly as hell with typescript.
I thought of doing a generic screen version, that would be hosted by a specific parent screen that would handle the navigation. But I'm then required to inject so many things from that parent screen (I need the navigation object in almost every component) which also leads to another typescript hell.
Also, almost every screen and complex component is a class component and not a functionnal one. No debate on the topic, it is as it is and can't be changed, so useNavigation() is out of the realm of possibilites right now (even with a HOC).

Adding dumb/presentational component on the navigation stack in React Native

tl;dr:
Is there a way to add a dumb/presentational React Native component on the React Navigation stack, so I don't leave the container when pressing the phones back button, but just show the previous component?
I cannot figure out how I should design my app. So far I have as many smart/container components as I have main pages (one for login, profile etc.) because my impression is that it is better to have few containers and more (presentaional) components.
So far I have only used top level navigation with React Navigation, but I have a flow where the user wants to book an appointment at the doctor.
My initial thought would be that I have one BookingContainer that renders different components, but I can't seem to figure a way to keep the navigation stack inside the one container, so now I have several containers (BookingMainContainer, BookingChooseDateContainer and BookingChooseTimeSlotContainer). The reason why I want one container is that much of the data I need is the same, so I want to just pass the data to the children instead of getting the (same) date from the state in the three related containers.

Pushing TabBar Controller on Navigation Controller

I am building an app in which at some point I have to show TabBar Controller but my app allready has Navigation Controller, so the most obvious sollution would be to push TabBar onto Navigation.
Apple in it's developer documentation states following:
"You never want to push a tab bar controller onto the navigation stack of a
navigation controller. Doing so creates an unusual situation whereby the tab bar appears only while a specific view controller
is at the top of the navigation stack.
Tab bars are designed to be persistent, and so this transient approach can be confusing to users."
Well I made it this way not knowing about this recomendation :). Now I am wondering if my app could me rejected because of this. Do you have any experiences with this? What do you think aboute this?
I don't think they're going to reject your app (not sure about it, but I don't think anyone can be), but your structure seems very confusing.
have a look at this: iOs Human Interface Guideline
For example:
"Use a tab bar to give users access to different perspectives on the same set of data or different subtasks related to the overall function of your app. When you use a tab bar, follow these guidelines:
Don’t use a tab bar to give users controls that act on elements in the current mode or screen. If you need to provide controls for your users, use a toolbar instead (for usage guidelines, see “Toolbar”).
In general, use a tab bar to organize information at the application level. A tab bar is well-suited for use in the main app view because it’s a good way to flatten your information hierarchy and provide access to several peer information categories or modes at one time."
I think you should transform your tab bar in a tool bar.