How to invoke App.js from inner component ReactNative? - react-native

I'm using StackNavigator to load a Tabbar created with react-native-tab-navigator in App.js. I have a view inside Tabbar. How can I navigate back to App.js from that view?
App.js
import { StackNavigator } from 'react-navigation';
const SigninSignup = StackNavigator({
Signup: { screen: Signup },
Signin: { screen: Signin },
});
render() {
if (this.state.condition) {
return (<Tabbar />);
} else {
return (<SigninSignup />);
}
}
Myview.js (It is inside Tabbar)
How can I go back to App.js and load SigninSignup ?
I have tried
const { navigate } = this.props.navigation;
navigate('Signin', {});
But getting ERROR undefined is not an object (evaluating 'this.props.navigation')

Your navigation hierarchy starts with the SigninSignup navigator.
Since your component is rendering either the navigator or your tab bar according to this.state.condition, you can't just navigate to the other screen.
You con solve this be either moving the tab bar and the SigninSignup navigator into a new root navigator and use that to navigate between everything, or by providing a function to Tabbar that would change the value of condition:
<Tabbar onSomething={() => this.setState({condition: !this.state.condition})} />

Related

How to add transition while navigating from one screen to other screen using react-navigation

I am using react-navigation to navigate from one screen to another screen. But while navigating I can see the navigation not good enough. So I am trying to add the transition while navigating from a screen to another screen. Any solution for this using react-navigation
if you want to just use react-navigation then use the following link
you will have to use Transitioner
class MyNavView extends Component {
...
render() {
return (
<Transitioner
configureTransition={this._configureTransition}
navigation={this.props.navigation}
render={this._render}
onTransitionStart={this.onTransitionStart}
onTransitionEnd={this.onTransitionEnd}
/>
);
}
or
You can use the following third party library for the Transition in navigation
Click Here
import { createStackNavigator } from 'react-navigation';
import { fromLeft } from 'react-navigation-transitions';
const appStack = createStackNavigator(
{
ScreenA: {
screen: ScreenA,
},
ScreenB: {
screen: ScreenB,
},
},
{
initialRouteName: 'ScreenA',
transitionConfig: () => fromLeft(),
},
);

React Native Open Tab Bar in Modal (using expo)

I'm trying to have one of the tab bar items open as modal when clicked, I'm currently using expo. I've read this: How do i make a TabNavigator button push a modal screen with React Navigation. However, I'm still learning React Native and I'm honestly not sure how to use this using expo navigation. Currently, I have created a stack navigator using "createStackNavigator" for each of the screens. And lastly, I have exported a bottom tab navigator including all of the stacks:
export default createBottomTabNavigator({
Tab1Stack,
Tab2Stack,
Tab3Stack,
Tab4Stack
});
I need Tab4 to open as a modal. Can someone people help me with this? Thank you in advance!!
Note this was built for "react-navigation": "3.3.0" so your mileage my vary for more recent versions of Expo and react-navigation.
To make a modal appear when you tap on the last tab in a TabNavigator requires you to nest your TabNavigator inside a StackNavigator.
So we could set up something like this:
#App.js
A simple App.js.
import React from 'react';
import AppContainer from './MainNavigation';
export default class App extends React.Component {
constructor (props) {
super(props);
this.state = {
};
}
render () {
return (
<AppContainer />
);
}
}
#MainNavigation.js
This file contains two navigators. A TabNavigator and a StackNavigator. The TabNavigator is nested inside the StackNavigator.
To be able to show the ModalScreen we have to override the tabBarOnPress function inside the defaultNavigationOptions which is inside the config for the TabNavigator.
We need to check the navigation.state.key to see where we are navigating too. If we are going to Tab3 we can intercept the call and navigate to the ModalScreen instead. Otherwise we use the defaultHandler and go to the tab that was tapped.
import Screen1 from './Screen1';
import Screen2 from './Screen2';
import Screen3 from './Screen3';
import ModalScreen from './ModalScreen';
import { createBottomTabNavigator, createAppContainer, createStackNavigator } from 'react-navigation';
const screens = {
Tab1: {
screen: Screen1
},
Tab2: {
screen: Screen2
},
Tab3: {
screen: Screen3
}
};
const config = {
headerMode: 'none',
initialRouteName: 'Tab1',
defaultNavigationOptions: {
tabBarOnPress: (data) => {
// this is where the magic happens
const { navigation, defaultHandler } = data;
// we check to see if the navigation key is going to be on Tab3
if (navigation.state.key === 'Tab3') {
// if it is we show the ModalScreen by navigating to it
navigation.navigate('ModalScreen');
} else {
// otherwise we call the defaultHandler and navigate to the tab we pressed
defaultHandler(navigation.state.key);
}
}
}
};
const TabNavigator = createBottomTabNavigator(screens, config);
const stackScreens = {
Tabs: {
screen: TabNavigator
},
ModalScreen: {
screen: ModalScreen
}
};
//we need to set the mode to be modal
const stackConfig = {
headerMode: 'none',
initialRouteName: 'Tabs',
mode: 'modal'
};
const MainNavigator = createStackNavigator(stackScreens, stackConfig);
export default createAppContainer(MainNavigator);
#Screen.js
A simple screen for each tab
import React from 'react';
import { View, StyleSheet, Text } from 'react-native';
export default class Screen extends React.Component {
render () {
return (
<View style={styles.container}>
<Text>Tab Screen</Text>
</View>
);
}
}
#ModalScreen
This screen is the modal that will appear when the tab for the third screen is tapped.
As it is part of the StackNavigator, defined above, it has access to the navigation prop. We set up a simple button that when pressed calls this.props.navigation.goBack() This will dismiss the modal.
import React from 'react';
import { View, StyleSheet, Text, Button } from 'react-native';
export default class Screen extends React.Component {
render () {
return (
<View style={styles.container}>
<Text>Modal Screen</Text>
<Button
title={'close modal'}
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
}
Here is a snack with it working, https://snack.expo.io/#andypandy/show-modal-on-tab-press, hopefully it will show you how to set it up.

React Navigation - goBack() is automatically invoked for stack navigator screen

I have 3 stack navigator screens (Home, Item List, Item Detail -> same order) inside drawer navigator and all three screens are hooked up to redux store with connect() helper.
When I do navigate('ItemDetail') from ItemList, it navigates to the screen and immediately comes back to ItemList screen. I am not sure why.
Following is my navigation structure -
const AppStack = createStackNavigator(
{
Home: {
screen: HomeScreen
},
ItemList: {
screen: ItemListScreen
},
ItemDetail: {
screen: ItemDetailScreen
}
},
{
initialRouteName: 'Home'
}
);
const DrawerNav = createDrawerNavigator(
{
DrawerApp: AppStack
},
{
drawerPosition: 'right'
}
);
const SwitchStack = createSwitchNavigator(
{
Loading: Loading,
Auth: AuthStack,
App: DrawerNav
},
{
initialRouteName: 'Loading'
}
);
This is how my each navigation screen component looks -
export class ProviderListScreen extends Component {
render() {
const { navigation } = this.props;
// ItemList is hooked up to Redux via connect() helper
return <ItemList navigation={navigation} />;
}
On my ItemDetail component, I get the Item data through route params from ItemList screen and I also dispatch an action (To reset some part of the store state) in component did mount. As soon as I do that, previous screen (ItemList) is automatically rendered.
Inside item detail, I make API call to create booking for that item and the booking object is managed by redux. Once I land on the ItemDetail, I reset the booking object for new booking data.
Here is the snippet of ItemDetail's componentDidMount -
componentDidMount() {
this.props.resetItembooking();
}
I am not sure what is causing this behaviour. If I remove the ItemList screen and jump directly to ItemDetail screen from HomeScreen, this issue does not occur.
Any help is appreciated.
I had the exact same problem however I tried the answer given in the original post comments sections given by Awadhoot but this did not work for me.
For anyone still trying to solve this issue, ensure you do not have any recurring intervals setup. Therefore you should always clear intervals before navigating away:
clearInterval(this.intervalId);
In react-navigation 5 you can use the useIsFocused hook for that:
import { useIsFocused } from '#react-navigation/native';
// ...
function Profile() {
const isFocused = useIsFocused();
return <Text>{isFocused ? 'focused' : 'unfocused'}</Text>;
}
From the docs: https://reactnavigation.org/docs/use-is-focused/

how to navigate to another screen in react native when fetch is done

I'm new in React Native and trying create my first app. So I have a question:
I got 2 screens (using react-navigation). At first screen there is a render of app logo with spinner(from native-base) and fetch to the server at the same time. And I need to navigate to another screen only when fetch is over and responce is handled. All I found at react-navigation docs is a solution with button, but it's not my case. Also I don't want to use ActivityIndicatorIOS (app should be correct for Android).
Please help me understand what should I do?
Thanks a lot!
Just call the navigate function in then callback of the fetch or handle error appropriately in catch.
Every screen in react-navigation gets the navigation prop. You can use the navigate function to navigate to any screen. Something like this
class FirstScreen extends React.Component {
static navigationOptions = {
title: 'First',
}
componentDidMount(){
const {navigate} = this.props.navigation;
navigate('Second');
fetch('http://apiserver').then( (response) => {
navigate('Second');
});
}
render() {
return (
<AppLogo />
);
}
}
const AppNavigator = StackNavigator({
First: {
screen: FirstScreen,
},
Second: {
screen: SecondScreen,
},
});

React-navigation StackNavigator render to specific screen

How can I render a Stack Navigator from React-navigation to a specific screen ?
Can I pass in a screen name as a prop to render the StackNavigator to that screen upon initial load?
UPDATE:
I solved it by passing in a prop to the Stack Navigator and then conditionally setting the intialRouteName:
const Main = RootNavigator(userLoggedIn);
then render the the Main like so <Main />
instead of the RootNavigator directly.
Then inside the Navigator code :
export const RootNavigator = (userLoggedIn= false) => {
return StackNavigator(
{
LoggedIn: {
screen: LoggedIn,
},
LoggedOut: {
screen: LoggedOut,
}
},{
initialRouteName: userLoggedIn? "LoggedIn" : "LoggedOut"
}
);
};
Yes, when you initialise your StackNavigator, the second parameters is the options. So you can do :
StackNavigator({ <Your-Routes> }, { initialRouteName: 'MyFirstPage' });