React native navigation after state change in redux - react-native

I am using react-redux and react-native's navigation in my app. My goal is of navigate after successful API call from Screen A -> Screen B -> Screen C and so on.
This is what I'm doing in the app.
On Screen A, button is pressed, and an redux action is generated.
Action is internally calling an API and getting result and dispatching event to reducer state.
After reducer's state gets updated (Success cases), I wanted to navigate to Screen B.
Again same 1-3 steps for Screen B to Screen C.
I did tried following approaches:
Adding navigation code in componentWillReceiveProps:
Problem with this approach is, its calling all the componentWillReceiveProps of navigation stack. This is rendering current screen multiple times before navigating to next screen (I observed this behaviour from Screen B -> Screen C)
Adding navigation code render method itself and returning null.
Again problem here is, what if I have multiple reducer mapped in one screen. Again I will be navigating more than once if both reducer changes.
I thought of using EventListener's, but than I have to keep track of adding and removing them.
Any ideas on how can I achieve this.
Thanks

Related

wix React-Native-Navigation: Would a parent screen on the stack ever be unmounted while user is viewing the child screen?

I’m using wix react-native-navigation with bottom tabs.
If i navigated to a screen say 2 levels deep from one of the root tabs (i.e. pushed two screens on the stack) so:
E.g.
RootTab_Screen1 -> ChildScreen2 -> Grandchild_Screen3
While I'm viewing GrandChild_Screen3, could either ChildScreen2 or RootTab_Screen1 ever be unmounted - if I don’t navigate away from this grandchild screen?
More specifically, if I passed a function from ChildScreen2 to Grandchild_Screen3, would ChildScreen2 be always there to respond to calling the function?
Thanks for your help.

Why React native navigation loads all components at the same time?

I am using react native navigation v2 by wix. I have a welcome screen with login screen and register. I start the startAuth.js from App.js. There are two tabs with login and register.
But as soon as app starts the componentWillMount methods runs in the register screen but yet i am at login tab.
Why is this happening?
react-native-navigation's Tab does not support lazy loading. But there are two special lifecyle functions where you can put your logic when component appear or disappear on screen
componentDidAppear(): called each time this component appears on screen
componentDidDisappear(): called each time this component disappears from screen
https://wix.github.io/react-native-navigation/docs/screen-lifecycle
There is also a discussion about topic https://github.com/wix/react-native-navigation/issues/1250

componentDidMount is not working when redirect to a screen

I am having componentDidMount to list set of files(images) in a screen A, from this screen A I am having another screen B link where I can see detailed view of a file and there I have an option to delete a document.
When screen A is called using
<TouchableOpacity style={Styles.HomeButton} onPress={ () => this.props.navigation.navigate('Gallery')}>
<Text style={Styles.HomeButtonText}>View Photos</Text>
</TouchableOpacity>
componentDidMount working fine, But when I delete a file (i am using react-native-fs) on unlink callback I am calling the navigation like
this.props.navigation.navigate('Gallery');
Which is working fine redirecting to Screen A, but componentDidMount is not working which means I can still see that deleted file in the list.
i.e Screen A is not refreshing, is there any possible solution?
In react-navigation, the component will not unmount if you navigate to other screens unless you reset the stack in stack navigation. So when you come back to the previous screen, as it is already mounted, componentDidMount will not trigger.
You can bind a react navigation event listener to trigger some piece of code when you get back to the screen.
this.focusListner = this.props.navigation.addListener("didFocus",() => {
// Update your data
});
Don't forget to remove event listeners while you unmount the component.
componentWillUnmount() {
// remove event listener
this.focusListner.remove();
}
Possible reason, why your componentDidMount() is not working, is because screen B may be possible a modal.
In the case of modals, the previous component does not unmount, and the next screen just opens upon it. So when you go back to the previous screen, it does not mount again. That's why your list is not updating.
Solution
You have to change the state of the component which is supposed to rerender. The best solution here, and which I also use, is a state management library like Redux. So when you delete the item from screen B, just also update the redux store accordingly. So every component that using that reducer will rerender and you can also save one hit to your server.
You should consider refreshing your list on navigation's didFocus event. Clearly if you are using a stack navigation with A -> B, and once you delete your file from B and goes back to A, provided that A is already in the stack so the didMount wont work when you navigate back.
So, ideally you must refresh your list on the didFocus event of the navigation using some kind of flag set in redux when you delete the file and once you get back to A you read the status of the flag and refresh your list accordingly.
You can refer this to better understand the navigation props and the lifecycle events
You may want to check the NavigationEvents API here : https://reactnavigation.org/docs/en/navigation-events.html .
To solve your problem you want to use the navigation event onDidFocus instead of componentDidMount !
This is a way easier way to than to use the imperative API as it takes care of subscribing and unsubscribing the listeners.

react-native-navigation update child data but remain parent data

I having problem when I push to next screen.
Lets say from screen A(product details screen) -> screen B(product details screen)
Currently I am successfully move from screen A to screen B. But the problems is when i navigate back to screen A, the data in screen A already updated which is same as screen B.
Below is how i update my screen data by using componentDidMount() and navigate to next screen using push.
componentDidMount() {
this.props.getDetails(id);
}
this.props.navigator.push({
screen:'myapp.productDetailsScreen'
})
Is it something i missed that accidentally update screen a data when i navigate to screen b?
Screen A and Screen B share the same component (they just render different value based on the id given).
I am using this library
react-native-navigation v1 (wix)
Any help is appreciated! Thanks.
if you are using redux you the redux state between both of the screens is shared. that is why it is updated on both screens.

How can I show a splash screen in React Native with React Native Navigation while loading app Redux state?

I am trying to integrate React Native Navigation by Wix into my application and am not sure how to go about setting things up to handle a loading phase.
The library has a splash screen at the native layer but that is only displayed while the bundle is being parsed. Once that is complete and React Native takes over, I then rehydrate my Redux store (from Redux-Persist), make a couple checks, call out to an API to validate a token, and redirect the user to the proper screen. While all of this is happening, I want to display a loading screen but have no idea how to go about it using this library.
I don't want to show my app or let the user use the app until all of the loading and checks have completed.
Is this possible with this library? If so, how do I set it up? My navigation is tab based, no side drawer.
There're 2 options for you:
1. Call Navigation.startSingleApp with the only screen is "Loading Screen" when app start. At that time, you call rehydrate redux. When the call back invoked, you call Navigation.start (single or tab) to your main screen
2. Design the registerScreen with route "Loading" for loading screen. When app start, call Navigation.startSingleApp for the loading screen. On "componentDidMount" of loading screen, call rehydrate redux, when call back invoke, push to Main screen