createBottomTabNavigator (navigation version 4) cannot use useEffect - react-native

I am using version 4 react navigation and particularly createBottomTabNavigator with createStackNavigator for each tab. For all implemented tabs, if I scroll away from my landing screen called home screen and return back to it, useEffect is not invoked. I do this with the use of navigation.navigate() to navigate to the home screen. I tried adding 'resetOnBlur' option and set it to true for the createBottomNavigator but it still does not blur and re focus such that useEffect can be invoked as per documentation when using navigation.navigate to reach a bottom navigator tab:
https://reactnavigation.org/docs/4.x/bottom-tab-navigator/
I want to do something on home screen load every time the user returns back to it by not tapping the bottom bar but when redirected through code with the use of navigator.navigate. How can I achieve this in. navigation version 4 ?

You can use useFocusEffect of react-navigation, like below,
import {useFocusEffect} from '#react-navigation/native';
useFocusEffect(
useCallback(() => {
// Do your work
}, []),
);

Related

React Navigation : How to prevent navigation to unmounted tab screen with Material Bottom Tab Navigator when Icon is pressed?

I have a question for React Native developers here. I use createMaterialBottomTabNavigator, and I wanted one button in the tab bar to open a screen not in a tab, but in a stack navigator instead. According to the documentation, we can prevent default behaviour with a useEffect hook in the target screen and do our navigation from there. So here is my code in the target screen :
useEffect(() => {
const unsubscribe = navigation.addListener("tabPress", (e) => {
// Prevent default behavior of tab press in bottom navigator
e.preventDefault();
// Open screen in stack navigator, not in tab navigator
navigation.navigate("TargetScreen");
});
return unsubscribe;
}, [navigation]);
It works well, except for one detail: Material Bottom Tab Navigator doesn’t mount its routes before they are first focused, so the first time I press the button it opens the screen in a tab. After that, when I press the same button, it opens the screen in a stack navigator as expected.
Does anyone know a workaround for that issue? Is there a way to force Material tab to mount routes before they are focused? Or a way to call a hook when the screen first mounts?
Thanks!

React-native componentWillMount not calling

I am new in react-native I have two screens in my stack. Login and Home.
I want to go back to login from a button on home.
I am writing this code
this.props.navigation.navigate('loginScreen')
but in login screen componentWillMount method is not calling. I want to reset my form when user come on login screen from home.
Can anyone help me here?
Thanks in advance.
The this.props.navigation.navigate('loginScreen') don't work because you are now in loginScreen.
If you want to restart page this code isn't good. because have a loop!
correct code:
just when navigate to loginScreen from home use:
this.props.navigation.push('loginScreen')
NOT IN "componentWillMount"
To go back from login from home , you should use this.props.navigation.goBack() if the screen is immidiately before home.
Secondly, you should not use componentWillMount since it is deprecated and will be removed from React 17 onwards. Instead use componentDidMount
Since the component is already mounted therefore it won't call the react lifecycle events componentDidMount again. Therefore you should use the react-navigation listeners didFocus event.
didFocus: the screen focused (if there was a transition, the transition completed)
componentDidMount () {
this._onFocusListener = this.props.navigation.addListener('didFocus', (payload) => {
// Perform the reset action here
});
}
Since your Home and Login Screens are both under the same StackNavigator, when you go from Home back to Login the state stays the same as the component doesn't unmount. The recommended way to solve this is using the SwitchNavigator of react-navigation. Read this very helpful part of the documentation below
https://reactnavigation.org/docs/en/auth-flow.html
You may not be familiar with SwitchNavigator yet. The purpose of
SwitchNavigator is to only ever show one screen at a time. By default,
it does not handle back actions and it resets routes to their default
state when you switch away.
The perfect solution is with this.props.navigation.push('Login'), I tried with SwitchNavigator but it doesn't provide navigationOptions for header.

React Native navigation actions

I have problem about navigation from other script (screen)... I implemented navigation in App.js (with createStackNavigator and with screens). Everything works fine when I want to navigate (with OnPress{() => navigate("someScreen")} to screen which is defined in this script (App.js).
But, when I want to use that navigation from other script (outside of App.js), let's say in "NewPage.js"
which has own "export default class NewPage..." and inside I have button element which task is to navigate "onPress" to screen which is defined in the App.js stackNavigator...
I know that I can't use anymore navigate("pageName") because navigation isn't implemented in this script and I tried with import { NavigationActions } from 'react-native' and inside of button element I tried with code: "this.props.navigation.navigate('somePage')" and it's not working.
So I don't know how to use navigation property from other script in which isn't implemented navigation, how to reference/export/import that property?
Here is code App.js script: https://pastebin.com/tLEFdQrE and NewPage.js script: https://pastebin.com/aVQGiinJ
This code is short so you can easily see what I want and what is the problem...
Thank you in advance!
Use this for better navigation among screen as compared to default navigation this is the better one for navigating among the screens. We mostly use this than other navigator
https://github.com/aksonov/react-native-router-flux
You should import your pages [using the names of the exported components, not the names of the js files] into your App.js.
For example, I stored my pages in a folder called 'screens' so when I imported my 'Home' screen, I used
import HomeScreen from './screens/HomeScreen.js';
which was further referenced as
Home: HomeScreen,
Good luck!

React Native get navigation object outside screen component

I need to be able to navigate and reset navigation stack from modules that are not necessarily screen components. It means, I can't use:
const {navigate} = this.props.navigation;
In my case, I need to properly redirect user to the right screen when he taps on push notification. I only have a callback:
onNotification: function(notification) {
// show correct screen and reset navigation stack
}
I just need more flexibility with navigation. So how can I do it for my case?
Here is my solution. I implemented base class for all screens. With this I always know what screen I am at and can always get navigation object to redirect user whenever needed:
import React, {Component} from 'react';
export default class Base extends Component {
static screen;
constructor(props) {
super(props);
Base.screen = this;
}
nav() {
return this.props.navigation;
}
}
In some other component/module I can just call this to navigate to a different screen:
Base.screen.nav().navigate(...);
I have created a navigation aware screen component to take care of it on screens.
For outside the screen you can directly access store.navigation. I have used it with redux in my example. See if this helps you.
https://github.com/aajiwani/react-navigation-aware-helper

how to get a splash screen first and then go the main home screen when using react-native-navigation?

I am using react-native 0.32.0 and "react-native-navigation": "^1.0.30", And I want to get a splash screen first and then go to the main home screen, where I begin to use react-native-navigation. I googled a lot and did a lot re research but still do not know how to make this. I try to get the simplest config passed to Navigation.startSingleScreenApp, but I still get the navbar in iOS. is it possible to get a raw splash screen first and then use react-native-navigation for navigation?
I implemented this through navigation experimental itself. you can refer this repository on github for navigation experimental https://github.com/jlyman/RN-NavigationExperimental-Redux-Example
I used setTimeout() function in the constructor of the page which I am loading first through my navigation experimental. The page in which I used this function became the splash screen of my app. Here is the code.
class FirstScreen extends Component{
constructor(props) {
super(props);
setTimeout(this.props.OnChange, 3000); //Constructor of Splash Screen page
}
//render() code
}
and here is my onChange() function inside mapDispatchToProps() which is calling navigatePush() action creater of my navigation experimental
OnChange: () => {
dispatch(navigatePush('Login'))
}