Adding dumb/presentational component on the navigation stack in React Native - 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.

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 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).

React Navigation infinite stack / dynamic stack

I would like to realise an infinite stack with react navigation, that means I would need a dynamic stacknavigator where I can push in a unlimited number of screens (a maximum of 20 screens would be enough). You can imagine this like in the amazon app where you can click on a related product in the product details and it shows you another product details screen where you can do the same thing.
Does anyone of you has an idea how to do that ?
This can be done with react-navigation
Instead of using this.props.navigation.navigate('ScreenName') you can use this.props.navigation.push('ScreenName')
You would probably want to pass some sort of description to the screen so that it knows what to render you can do that by passing params
this.props.navigation.push('ScreenName', { key: productId })
You would just have to set up a few template screens that could then be populated by the parameters that you pass to them.
You can see more about the different functions that react-navigation has here
https://reactnavigation.org/docs/en/navigation-prop.html#navigator-dependent-functions
Here is a snack showing it working https://snack.expo.io/#andypandy/infinite-navigation
In the snack I pass a position and date, you can see these update as each screen is pushed onto the stack. Pressing Go Back goes back one place on the stack.

Multiple instances of one component in React Native

I am new to React Native and am working on a simple app, the app loads data structured like file folder hierarchy, so at top level, when a item is clicked, I want to switch to next level and Etc. every level has the same data, I guess I need to use the same component, I want to use react navigation to switch between levels, but I cannot do this because the same component is used.
Of course you can say just change the components' state with different data, but I need the navigation animation effect and navigating to upper level when click the back navigation component at the top.
Please help, thanks]1
Since I am using StackNavigation, using "push" is the answer,
this.props.navigation.push('ScreenName');
see this link: https://reactnavigation.org/docs/en/navigating.html

Navigator and multiple views in React Native

I am playing around with React Native and trying to build a test application. I am stuck at the Navigator part: https://facebook.github.io/react-native/docs/using-navigators.html.
I understand that one can change the state of the variables (as they are doing in the tutorial, increasing the index variable). What I don't really understand is how I could render different Components based on which button is clicked in my menu. In the example, it is always "MyScene" that is rendered, but with different values. How should I do to render "MyScene2" when clicking on some button?