Ability to get navigation screens state, with stacks, components, props and options.
Yes
imagine a Chat app which contains ChatsListScreen, NewChatScreen and ChatScreen itself. The user can navigate ChatsListScreen <-> ChatScreen, which makes perfect sense.
But what if the user goes from ChatsListScreen -> NewChatScreen and selects a user to create a new chat with? The user then lands in the ChatsScreen as expected, but should not go back to the NewChatScreen when the back button is pressed. In this case you would want to reflect the navigation state and check out if there is a NewChatScreen "in the middle" so you can directly pop to the ChatsListScreen instead
From the user's point of view, I think it would be logical to make a method to get the state of navigation.
const state = Navigation.getState();
It would also not be superfluous to be able to subscribe to its change.
const { unsubscribe } = Navigation.addStateChangeListener(callback); // unsubscribe from corresponding code
Navigation.removeStateChangeListener(callback); // unsubscribe from anywhere else
I deliberately will not suggest a data structure to represent the state.
Instead, I will describe what it should contain:
I like that idea. I'm not exactly sure why we don't expose a state already (@guyca can you fill us in here?), but I can imagine the data structure in which the stack should be represented can get quite complicated. How do you display the following:
Would we just show a queue in this case and treat modals as full-screen screens?
I will leave my examples where the presence of such storage was help me a lot in a real application
1) When opening a push notification that should take the user straight to some screen, knowing which screen is at the top prevents me from opening it again.
Case:
2) By design I have a custom header. It has a back button with arrow/cross icon.
This button looks at the store, and understands what it should do:
-If this is the last screen in the modal stack, it closes the modal
-if its not the last one , it does pop
-its decide icon: x-mark/arrowLeft
3) Business logic with the behavior of the application, depending on which path it took to get to the screen
3.5) it was handy to make breadcrumbs with this store
And these are just my cases
@mrousavy @Natteke Exposing the navigation state is such a great idea! We have tried multiple different solutions over time but never really settled on any concrete pattern. Have you guys got any suggestion in how to actually expose these states across all registered screens? In the past, we have experimented with React Context as you can see in the documentation however there are some known limitations such as state changes not triggering the re-rendering on all registered screens as they are on a separate component tree. However solutions that utilise Proxies (we simply used MobX) can be used to combat this limitation.
What about using an actual Stack data structure natively and update that stack based on what the user do?
It makes sense since once you pop anything from your screens it will be reflected in that stack.
Then just offer a native event that you can subscribe to, to query the stack state.
@mateioprea I feel like there's no reason to do this natively, as that results in extra & unnecessary bridge traffic. We can do this in JS as an actual "queue" and on changes we raise events 🤷♂️
this would allow setting the theme dynamically without needing to reset the navigation, correct ?
@Natteke
Example
imagine a Chat app which contains
ChatsListScreen,NewChatScreenandChatScreenitself. The user can navigateChatsListScreen<->ChatScreen, which makes perfect sense.
But what if the user goes fromChatsListScreen->NewChatScreenand selects a user to create a new chat with? The user then lands in theChatsScreenas expected, but should not go back to theNewChatScreenwhen the back button is pressed. In this case you would want to reflect the navigation state and check out if there is aNewChatScreen"in the middle" so you can directly pop to theChatsListScreeninstead
I think there is something wrong in the layout you described, you should open the NewChatScreen as a modal, it's not actually related to the chat stack.
I would first suggest to open NewChatScreen as a modal, when the user finish's creating the new chat, dismiss the modal and push the ChatScreen normally to the stack (See What'sApp implementation).
I'm not sure about this feature because most times you need to know how the layout hierarchy look like, it means something is wrong with the usage or the hierarchy itself.
Let's try to find more use cases where we need it.
@yogevbd, this example was provided by @mrousavy. He edited the issue.
My reall app use cases are in comment.
But i think i will gather more from my colleagues next week.
Also i will try to figure out a data stucture to represent the store.
So far, on draft, it looks complicated
this would allow setting the theme dynamically without needing to reset the navigation, correct ?
@a-eid, in this proposal I only brought up the question of getting detailed information about the current state of the navigation/screens.
Most helpful comment
@mateioprea I feel like there's no reason to do this natively, as that results in extra & unnecessary bridge traffic. We can do this in JS as an actual "queue" and on changes we raise events 🤷♂️