React navigation return to previous screen immdiately - react-native

Trying to add navigation to React Native app with Redux and Saga. It work for one screen but when adding AppNavigator like this one it behaves strange
import HomeScreen from '../screens/fake/HomeScreen';
import LoginScreen from '../screens/fake/LoginScreen';
import SplashScreen from '../screens/fake/SplashScreen';
export const AppNavigator = createStackNavigator({
Splash: SplashScreen,
Home: HomeScreen,
Login: LoginScreen
});
Each screen is control like this one:
class HomeScreen
extends React.Component {
render() {
return (
<View>
<Button
title="Go to Login"
onPress={() => this.props.navigation.navigate('Login')}
/>
<Button
title="Go to Splash"
onPress={() => this.props.navigation.navigate('Splash')}
/>
</View>
);
}
};
i.e. contains only button that should navigates to another screen. And it does. But after that happens event Navigation/NAVIGATE that return user to previous page.
First event Navigation/NAVIGATE contains correct route key. But second occurence - Navigation/COMPLETE_TRANSITION (more exact: {type: "Navigation/COMPLETE_TRANSITION", key: "StackRouterRoot"}) return user to previous screen.
Any ideas?

Related

How to navigate to another screen from a function component?

I have a tabBarNavigation and i have a Home component. In the Home component i want to be able to navigate between two different screens. I have a component called ReadButton which when pressed should take me to another screen called 'BookScreen'. Now i have written so my HomeStack component have two screens 'HomeScreen' and 'BookScreen'. My problem is i cant make the 'ReadButton' to navigate to 'BookScreen' when pressed. It says ''Undefined is not an object(evaluating props.navigation.navigate).
...//This is in the main class provided by react
const HomeStack = createStackNavigator(
{
Home: HomeScreen,
Book: BookScreen,
},
config
);
const tabNavigator = createBottomTabNavigator({
HomeStack,
LinksStack,
SettingsStack,
});
tabNavigator.path = '';
export default tabNavigator;
...
//Below is the ReadButton class in a seperate file
import {withNavigation} from 'react-navigation'
const ReadButton = (props) => {
const [ReadPressed, setReadPressed] = useState(true)
const {navigate} = props.navigation.navigate
if(ReadPressed){
return(
<View>
<TouchableOpacity style={styles.buttonstyle} onPress={navigate("Home")}>
<Text style={styles.textstyle}> READ </Text>
</TouchableOpacity>
</View>
)
}
else {
return(
props.book
)
}
}
// Another class where i have my <ReadButton>
function BookCover(){
<TouchableOpacity style={styles.bottomFlexItemWhenClicked} onPress= .
{() => setBookCoverState(true)}>
<Text style={styles.BackgroundText}>{props.text}</Text>
<ReadButton book={props.book} navigation={props.navigation}>
</ReadButton>
</TouchableOpacity>)}
}
export default withNavigation(ReadButton);
Now i have tried putting 'Book: BookScreen' over 'Home: HomeScreen' and then the screen actually shows but i cant navigate between them. What am i missing?
Maybe you can try hooks?
install hooks: yarn add react-navigation-hooks#alpha
and then use it in your function component:
import { useNavigation } from 'react-navigation-hooks'
export default function Screen1 () {
const { navigate } = useNavigation()
return (
<Button
title='Try'
onPress={() => { navigate('Screen2') }}
/>
)
}
Please note that components inside the HomeScreen or BookScreen won't receive the navigation prop.
1.Either you send them manually like this
<ReadButton navigation={this.props.navigation}/>
or
2.Use the built in withNavigation of react-navigation like this
import {withNavigation} from 'react-navigation'
const ReadButton=(props)=>{}//Now you can access navigation prop here
export default withNavigation(ReadButton)
Second method will come to handy when your component is deeply nested and you want to access the navigation prop without manually passing the props.

How to navigate from ListItem (react-native-elements) to new screen?

How do I navigate to a new screen on touching a ListItem ? I have ListItems with Chevrons towards right, giving an impression that touching the ListItem would take to detailed screen. A detialed screen would then take back to original ListItem screen.
My ListItem is in Menu.js, I have a screen Home.js, imported into Menu.js I then put Home screen in
const ListitemDetail = createStackNavigator({
Home: Home
});
I then used ListitemDetail react element in my ListItem
<ListItem
key={i}
title={item.title}
leftIcon={{ name: item.icon }}
bottomDivider={true}
chevron
onPress={() => this.props.navigation.navigate("ListitemDetail")}
/>
It is not navigating to ListitemDetial's Home.
But when I use 'Home' directly, it is taking me to Home screen, downside of doing this is, I can not go back (back arrow wont show up on header, obviously)
onPress={() => this.props.navigation.navigate("Home")}
Here is my Menu.js
import React, { Component } from "react";
import {
Text,
StyleSheet,
View,
Animated,
ScrollView,
SectionList,
SafeAreaView,
FlatList
} from "react-native";
import { createStackNavigator } from "react-navigation";
import Home from "./Home";
import { ListItem } from "react-native-elements";
const ListitemDetail = createStackNavigator({
Home: Home
});
const list2 = [
{
title: "Appointments",
icon: "av-timer"
},
{
title: "Trips",
icon: "flight-takeoff"
}
];
export default class Menu extends Component {
render() {
return (
<SafeAreaView>
<ScrollView>
<View>
{list2.map((item, i) => (
<ListItem
key={i}
title={item.title}
leftIcon={{ name: item.icon }}
bottomDivider={true}
chevron
onPress={() => this.props.navigation.navigate("ListitemDetail")}
/>
))}
</View>
</ScrollView>
</SafeAreaView>
);
}
}
Ideally what i want to achieve is something like a 'Setting' screen on whatsapp or 'Menu' screen on Facebook. Is there a better way of doing this ?
You have some issues with your Screens.
You only have one Screen in createStackNavigator, which is called Home.
This way, if you call an non existing Screen, it falls back to the first one declared in createStackNavigator.
So try it like this:
const MyApp = createStackNavigator({
Home: { screen: HomeScreen },
DetailScreen: { screen: DetailScreen },
});
AppRegistry.registerComponent('MyApp', () => createAppContainer(MyApp));
This way, Home is the first Screen comes up after starting the app.
I assume, you have your ListItem-Component in HomeScreen, and you use withNavigation() in the export of this ScreenComponent to make your navigator available via the props.
Then you can switch to another Screen simply by using:
onPress={() => this.props.navigation.navigate(
"DetailScreen",
{ myParamsToThisScreen:
{test: true,
param1: false
}
})}
Give it a try this way (and don't forget to vote up this answer if it's helps you out)

React-Navigation: Navigation onPress doesn't work

I am a bit confused about this navigation system. I have root which I contain navigations in it. And I have two different screens. No problem till here. I put initialRoute and displaying SignInScreen. Also put a button for Sign Up screen but that button isn't working.
Root.js
const ScreenNavigator = createStackNavigator({
SignIn: SignInScreen,
SignUp: SignUpScreen,
},
{initialRouteName: 'SignIn' }
);
const ScreenContainer = createAppContainer(ScreenNavigator);
export default class Root extends Component{
render(){
return(
<ScreenContainer style={styles.container} />
);
}
}
and SignInScreen:
import SignUpScreen from '../screens/Signup';
export default class SignInScreen extends Component{
constructor(props){
super(props);
}
render(){
return(
<View style={styles.container}>
<Text>Sign in Screen </Text>
<Button
title={'Sign up'}
onPress={() => this.props.navigation.navigate('SignUpScreen')}
/>
</View>
);
}
}
is it something that I am missing here? Thank you for help.
There is nothing wrong in the code, you just miss spell the route.
There is no route name SignUpScreen, correct route name is SignUp and SignIn
confusion is due to change in api of react navigation
before we define a route like
Login: {
screen: LoginScreen
}
so login is a route name and screen is just a component we need to render
but after 2^ version, it changed to
{SignIn: SignInScreen}
so now name is SignIn and component is SignInScreen
even if you want a route name as component just do
const ScreenNavigator = createStackNavigator({
SignInScreen,
SignUpScreen,
},
now you route name is SignInScreen and SignUpScreen
hope this information is enough
Issue in route name.
onPress = {() => this.props.navigation.navigate('SignUp')}
Try to keep the route names in constant file. It may make things easier to handle.
const routes = {
route1: 'route1',
route2: 'route2',
};
const ScreenNavigator = createStackNavigator({
[routes.route1]: Screen1,
[routes.route2]: Screen2,
},
{initialRouteName: routes.route1 }
);

How do I redirect in react native when button is clicked?

How do i go to the next screen in react native when i clicked a button?
Here is my code
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Button,
} from 'react-native';
import Test from './android/components/Test'
export default class ReactTest extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome click the button to register.
</Text>
<Button
style={styles.cancelButton}
onPress={this.editUser}
title="Register"
color="#343434"
accessibilityLabel="Register a User."/>
</View>
);
}
}
I am new to react-native. I am trying to navigate from one screen to another when the register button is pressed.
Write a function at the top before render method for editUser to direct where to navigate to.
editUser = () => {
this.props.navigation.navigate("Screen");
};
You can use any of the following api
React Native Router
NavigatorIOS
React Navigation
Navigator
But I recommend you to use React Navigation. Here is an example how to use React Navigation
import {
StackNavigator,
} from 'react-navigation';
const App = StackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
});
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
title="Go to Jane's profile"
onPress={() =>
navigate('Profile')
}
/>
);
}
}

using DrawerNavigator as main UI, app always enter default item screen without displaying drawer items

I'm developing an app with ReactNative and React-Navigation.
And I set a DrawerNavigator as main UI.
But when app launches, it will always enter default item screen, without displaying drawer item.
What am I missing?
React-Navigation version: "2.18.2"
code of App.js is as the following. When it runs, App UI shows "page1" instead of showing 2 draw items 'page1' and 'page1'
import React, {Component} from 'react';
import {Text, View} from 'react-native';
import { DrawerNavigator } from 'react-navigation';
class Page1 extends Component {
render () {
return (
<View style={{padding: 50}}>
<Text>
Page1
</Text>
</View>
);
}
}
class Page2 extends Component {
render () {
return (
<View style={{padding: 50}}>
<Text>
Page2
</Text>
</View>
);
}
}
const DrawerNavi = DrawerNavigator({
Page1: {
screen: Page1
},
Page2: {
screen: Page2
}
});
export default class App extends React.Component {
render() {
return <DrawerNavi />;
}
}
const DrawerNavi = createDrawerNavigator({
Page1: {
screen: Page1
},
Page2: {
screen: Page2
}
});
You should use createDrawerNavigator instead of DrawerNavigator. I don't actually understand what you mean by "When it runs, App UI shows "page1" instead of showing 2 draw items 'page1' and 'page1'"
The drawerNavigator will show your drawerItems on the left or right (depending on where you want to place it) then you can swipe left/right to access it. It also demands that you have a default screen. You can change this default screen by passing initialRouteName to the component.
You can read more about the drawerNavigator here: https://reactnavigation.org/docs/en/drawer-navigator.html