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 }
);
Related
I am trying to login user after Rehydration in react-native. I am not sure how to go about redirecting user after I have data in the store.
Here is how I setup my PersistGate in my index.js file:
class AppRedux extends React.Component {
render() {
return (
<Provider store={store}>
<PersistGate persistor={persistor} loading={<SplashScreen />}>
<App />
</PersistGate>
</Provider>
);
}
}
AppRegistry.registerComponent(appName, () => AppRedux);
SplashScreen.js:
class SplashScreen extends Component {
constructor(props) {
super(props);
props.navigation.navigate(RouteNames.Home);
}
render() {
return <View style={{ flex: 1, backgroundColor: "green" }}></View>;
}
}
const mapStateToProps = state => {
return {
rehydrated: state.user.rehydrated
};
};
export default connect(mapStateToProps)(SplashScreen);
The problem with this approach is that I am not able to navigate from splash screen. I get Navigation prop is undefined.
"loading" prop in "PersistGate" is just a dummy component to show loader until Persist Rehydration . "App"(navigation component) will load after Rehydration where you can receive "navigation" prop and can access store.
Try this like described in official site Auth Flow
Create AuthLoading Screen and set navigation from there
App.js
const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = createStackNavigator({ SignIn: SignInScreen });
export default createAppContainer(
createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: AppStack,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
}
)
);
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.
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?
My app root component looks like this:
export default class App extends React.Component {
render() {
<RootTabs doThings={this.doThings} />
}
}
The RootTabs component is created by createBottomTabNavigator from react-navigation:
const RootTabs = createBottomTabNavigator({
Movies: {
screen: Movies
},
Actors: ... // etc
})
My problem is, I would like to transmit data (as a prop if possible) from the root component (App) to the Movies component, but Movies do not receive the doThings prop.
How to transmit props through a BottomTabNavigator to children?
If that's not possible, what would be the most simple way for a children component to call a method on a root component, when they are separated by a BottomTabNavigator?
Try using screenProps
screenProps is documented on this page
Answered referred from here
Minimal Example would be
import React, { Component } from 'react'
import { AppRegistry, Button, Text, View } from 'react-native'
import { StackNavigator } from 'react-navigation'
class HomeScreen extends Component {
render() {
const { navigation, screenProps } = this.props
return (
<View>
<Text>Welcome, {screenProps.user.name}!</Text>
<Button onPress={() => navigation.navigate('Profile')} title="Go to Profile" />
</View>
)
}
}
class ProfileScreen extends Component {
render() {
const { navigation, screenProps } = this.props
return (
<View>
<Text>My Profile</Text>
<Text>Name: {screenProps.user.name}</Text>
<Text>Username: {screenProps.user.username}</Text>
<Text>Email: {screenProps.user.email}</Text>
<Button onPress={() => navigation.goBack()} title="Back to Home" />
</View>
)
}
}
const AppNavigator = StackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
})
class MyApp extends Component {
render() {
const screenProps = {
user: {
name: 'John Doe',
username: 'johndoe123',
email: 'john#doe.com',
},
}
return (
<AppNavigator screenProps={screenProps} />
)
}
}
export default MyApp
AppRegistry.registerComponent('MyApp', () => MyApp);
HomeScreen and ProfileScreen are components defined as screens for AppNavigator.
In the example above, I am passing the user data from the top-level, root component MyApp to both HomeScreen and ProfileScreen.
Since there is a AppNavigator between MyApp and the screen components, we will need to pass the user to screenProps prop of AppNavigator, so that the AppNavigator will pass it down to the screens. Any other prop except screenProps will not be passed down.
MyApp <-- user data here .
AppNavigator <-- the StackNavigator, the middle man. must use screenProps to pass user data down .
HomeScreen <-- will receive user data from this.props.screenProps.user instead of this.props.user .
ProfileScreen <-- same as HomeScreen
I want to close the Drawer on screen: ExportClues, but it is not working.
This is my code.
const Drawer = DrawerNavigator( {
Navigators: {
screen: Navigators
},
{
initialRouteName: 'Navigators',
drawerWidth: Metrics.screenWidth - 95,
drawerPosition: 'right',
contentComponent: MenuNavigator
}
})
const Navigators = StackNavigator({
...screen
})
const MenuNavigator = StackNavigator({
ExportClues: {
screen: ExportClues,
},
...other screen
})
It is ExportClues Component:
export default class index extends Component {
render() {
return(
<View
style={{flex: 1, backgroundColor: '#ffffff'}}
>
<TouchableOpacity
onPress={()=>{
this.props.navigation.navigate('DrawerClose');
// It is not work
}}
>
<TouchableOpacity/>
</View>
)
}
}
Sorry, My english is very poor.
How to get MenuNavigator Parent Navigator as DrawerNavigator?
Looking at the link you provided, you are trying to include the Drawer component incorrectly:
You write
import Drawer from './drawer'
and try to use component
but your drawer.js file is exporting "CustomerManagerDrawerNavigator"
export default CustomerManagerDrawerNavigator;
which means your code should be
import CustomerManagerDrawerNagivator from './drawer'
and your component should be called as
in the render() function.
If you want to use DrawerNavigator you need to to change your
const MenuNavigator = StackNavigator({
to
const MenuNavigator = DrawerNavigator({
to close the drawer while in ExportClues, you would call
this.props.navigation.navigate('DrawerClose'); // close drawer
which I see you have but you aren't passing any navigationOptions to in your Navigator configuration, so you don't have access to the navigate function. You need something like the code below:
navigationOptions: ({navigation}) => ({
.../*Your navigation options here */
}),
to pass navigation as a prop to your open Drawer
I would review the React-Navigation homepage for DrawerNavigator located at https://reactnavigation.org/docs/navigators/drawer for more details or if possible post a link to a working repository