React native navigation from seperated class files - react-native

I'm just started learning React Native. Used create-react-native-app. Code works as well. I can navigate my screen to Details from HomeScreen.
App.js file:
class HomeScreen extends React.Component {
render() {
_onPressButton() {
this.props.navigation.navigate('DetailsScreen');
}
return (
// Views
);
}
}
class DetailsScreen extends React.Component {
render() {
return (
// Views
);
}
}
const RootStack = StackNavigator(
{
HomeScreen: { screen: HomeScreen, },
DetailsScreen: { screen: DetailsScreen, },
},
{ initialRouteName: 'HomeScreen', }
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}
Then i separated HomeScreen and DetailScreen into individual js file from App.js file. And now i am unable to navigate them. What makes it unable to navigate them?
App.js file:
import ...
import HomeScreen from './screens/homeScreen';
import DetailsScreen from './screens/detailsScreen';
const RootStack = StackNavigator(
{
HomeScreen: {screen: HomeScreen,},
DetailsScreen: {screen: DetailsScreen,}
},
{ initialRouteName: 'HomeScreen', }
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}
HomeScreen.js file
import ...
export default class HomeScreen extends React.Component {
_onPressButton() {
Alert.alert('You tapped the button!');
this.props.navigation.navigate('DetailScreen');
}
render() {
return (
// View
);
}
}

Related

React Native Navigation Root issue with multiple views

Hello All I am facing an issue.
I am trying to set different root in app.js file but it always open Home View. Can anyone tell me what is wrong with my code. Any help would be highly appreciable!
import React, { Component } from "react";
import { View, Text, AsyncStorage, AppRegistry } from "react-native";
import LoginContainer from "./Login/LoginContainer";
import { createStackNavigator, createAppContainer } from "react-navigation";
import Home from "./Dashboard/Home";
const RootStack = createStackNavigator(
{
login: { screen: LoginContainer },
Home: { screen: Home }
},
{
initialRouteName: "login"
}
);
const AppContainer = createAppContainer(RootStack);
class Demo extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
email: ""
};
}
componentDidMount() {
const email = AsyncStorage.getItem("email").then(email => {
this.setState({
isLoading: false,
email: email
});
});
}
render() {
if (this.state.isLoading) {
return (
<View>
<Text>Loading..</Text>
</View>
);
}
if (this.props.email !== "") {
return <Home />;
} else {
return <AppContainer />;
}
}
}
export default Demo;
AppRegistry.registerComponent("Demo", () => Demo);
Instead of
export default Demo;
Use this :
export default AppContainer;
or
export default createAppContainer(RootStack);

How do i switch screens from one file to another

I'm very new to react native so please explain carefully.i have 3 files App.js SplashAndLogin.js and Register.js Im able to get from the initial screen to the register screen and go back and forth between my components in my Register file but when its time to go back to the Login screen i always seem to get the same error.
I've tried several different things but they all keep giving me the same error. im starting to think the way i set up my files are just wrong.
//App.js
class App extends Component<Props> {
render() {
return (
<AppContainer/>
)
}
}
export default App
const AppSwitchNavigator = createSwitchNavigator(
{
Login: {screen: SplashAndLogin},
//Registe :{screen: Register}
});
//SplashAndLogin.js
class SplashAndLogin extends Component<Props> {
render() {
return (
<AppContainer/>
)
}
}
export default SplashAndLogin;
const SAndLAppNavigator = createSwitchNavigator(
{
SandL : {screen: LoadingScreen },
RegisterScreen : {screen: Register}
}
);
//Register.js
export default class Application extends Component<Props> {
render() {
return (
<AppContainer/>
);
}
}
const AppSwitchNavigator = createStackNavigator(
{
Login :{screen: NameScreen},
PhoneAndEmail: {screen: EmailPasswordScreen},
HomeScreen: {screen: SplashAndLogin },
UploadScreen: {screen: CertificateUploadScreen }
});
const AppContainer = createAppContainer(AppSwitchNavigator);
So to summarize i can get to every screen except when im on the Register.js file and try to navigate to the HomeScreen it throws out the error
"The component for route 'HomeScreen' must be a react component For example...."
It's normal, you are using two different AppContainer.
You can not call a view in another AppContainer from the current AppContainer
this.props.navigation
refers to the current navigation
Use the state to change AppContainer
class RenderAppContainer extends Component {
constructor(props) {
super(props);
this.state = { IsConnected : false }
this.changeIsConnected = this.changeIsConnected.bind(this)
}
changeIsConnected = () => {
this.setState((prevState, props ) => ({ IsConnected : !prevState.IsConnected}))
}
render() {
cons {IsConnected } = this.state
return(
<React.Fragment>
{(IsConnected) ? AppContainerOne : AppContainerTwo } 
</React.Fragment
)
}
}
You can then pass changeIsConnected to your AppContainer
<AppContainerOne screenProps={{changeConnected: this.changeIsConnected}} />
<AppContainerTwo screenProps={{changeConnected: this.changeIsConnected}} />
https://reactnavigation.org/docs/en/stack-navigator.html
see documentation for ScreenProps

Using react-navigation 3.* how to navigate from screen to same level BottomTabNavigator?

I got react native app with such structure:
./App.js
./screens/AppNavigator.js
./screens/SignInScreen.js
./screens/HomeScreen.js
./screens/FavoritesScreen.js
App.js:
import { createAppContainer } from "react-navigation";
import AppNavigator from './screens/AppNavigator';
const AppContainer = createAppContainer(AppNavigator);
export default class App extends React.Component {
render() {
return (
<View>
<AppContainer/>
</View>
);
}
}
screens/AppNavigator.js:
import { createSwitchNavigator, createBottomTabNavigator } from 'react-navigation';
import SignInScreen from './SignInScreen';
import HomeScreen from './HomeScreen';
import FavoritesScreen from './FavoritesScreen';
const AppBottomTabNavigator = createBottomTabNavigator({
Home: {
screen: HomeScreen
},
Favorites: {
screen: FavoritesScreen
}
},
{
initialRouteName: 'Home',
});
export default createSwitchNavigator(
{
App: AppBottomTabNavigator,
Auth: SignInScreen
},
{
initialRouteName: 'SignInScreen',
}
);
screens/SignInScreen.js:
export default class SignInScreen extends React.Component {
render() {
return (
<View>
<Button title="Continue w/o sing in..." onPress={this.toApp} />
</View>
);
}
toApp = () => {
this.props.navigation.navigate('App'); // from here I try to navigate to Home screen
};
}
And when I try to navigate to HomeScreen from SignInScreen I see white screen instead of HomeScreen, though all other navigation works well.
The problem do not occur if in screens/AppNavigator.js I change createBottomTabNavigator to createSwitchNavigator, got no idea why. A problem also do not appear if in screens/AppNavigator.js I navigate direct to HomeScreen or FavoritesScreen instead of AppBottomTabNavigator.
I found this thread on github, but, as I understand, it's not related for me, because both AppBottomTabNavigator and SignInScreen are childs of AppNavigator.
So, what is weong with my code?
The problem is in de App.js. For some reason you can't put a BottomTabNavitation inside a View Component, so remove. Like this:
export default class App extends React.Component {
render() {
return (
<AppContainer/>
);
}
}
You should also change the parameter initialRoutName in createSwitchNavigator. You have to put the routName, in this case Auth.
export default createSwitchNavigator(
{
App: AppBottomTabNavigator,
Auth: SignInScreen
},
{
initialRouteName: 'Auth',
}
);

How to create a Drawer Component and adding it to multiple screens

Hi i want to create a component by using a createDrawerNavigator, and want to add it all screens could you help me.
In the below example don't copy all the syntax understand the concept from my explanation I have configured redux and many other imports you may not need so configure and include content in below files as you need.
File name - BurgerMenu.js
import React, { Component } from "react";
import SideBar from "./SideBar.js";
import News from "../../Containers/News"; // import your screens instead
import Copyright from '../../Containers/Gallery' // import your screens instead
import { DrawerNavigator } from "react-navigation";
const BurgerMenu = DrawerNavigator(
{
News: { screen: News },
RulesOfUse: { screen: RulesOfUse },
Copyright: { screen: Copyright }
},
{
contentComponent: props => <SideBar {...props} />
}
);
export default BurgerMenu;
File name - SideBar.js
In this file specify the layout, any actions like navigation, api call etc of drawer as you want which is imported to above BurgerMenu.js file
/*
SideBar.js
Component used to render contents of SideBar
*/
import React from 'react';
import { View, Modal, Text, Linking } from 'react-native';
const {
modalBackground,
topContentStyle,
bottomContentStyle
} = styles;
class SideBar extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
}
render() {
return (
<View
elevation={5}
style={modalBackground}
>
</View>
);
}
}
export default SideBar;
And in the App.js import Burgermenu.js to StackNavigator
import React, { Component } from 'react'
import { Provider } from 'react-redux';
import { StackNavigator } from 'react-navigation';
import Splash from './src/App/Containers/Splash';
import Login from './src/App/Containers/Login';
import InformationPage from './src/App/Containers/Gallery'
import BurgerMenu from './src/App/Components/BurgerMenu/index'
import configureStore from './src/RNRedux/ConfigureStore';
// Manifest of possible screens
const PrimaryNav = StackNavigator({
Splash: { screen: Splash },
Login: { screen: Login },
Home: { screen: BurgerMenu },
InformationPage: { screen: InformationPage }
}, {
// Default config for all screens
headerMode: 'none',
initialRouteName: 'Splash',
});
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
channelId: ""
};
this.store = configureStore();
}
componentDidMount() {
}
componentWillMount() {
}
render() {
return (
<Provider store={this.store}>
<PrimaryNav />
</Provider>
);
}
}
Just open the burger menu from any the screens imported to BurgerMenu.js
In my example you can open it from news.js and gallery.js which are imported to BurgerMenu.js.
Just use below functions for open and close
openBurgerMenu() {
this.props.navigation.openDrawer();
}
closeBurgerMenu() {
this.props.navigation.closeDrawer();
}

How to send parameters from screen to stack navigator?

I am a newbie to react native.
I am using a stack navigator inside a tab navigator; I have to navigate multiple screens inside each tab. i am able to send parameters from my default class HomePage to my nested classes in my tab and stack navigators.
export const MyApp = TabNavigator({
Asset: {
screen: AssetScreen,
},
Sensors: {
screen: sensorsStack,
},
Settings: {
screen: settingStack
},
}
export const sensorsStack = StackNavigator({
sensors : { screen: SensorScreen },
sensorDetails : { screen: SensorDetails }
});
export const settingStack = StackNavigator({
settings: { screen: SettingsScreen },
about : { screen: About },
environment : { screen: Environment }
});
export default class HomePage extends Component {
constructor(props) {
super(props);
this.state = {
assetID:'xyz',
authToken:'xyzz'
}
}
static navigationOptions = {
header: null
};
render() {
const screenProps = {
asset: {
assetID: this.state.assetID,
authToken : this.state.authToken,
},
}
return (
<MyApp screenProps={screenProps} />
);
}
}
Now, i want to send a parameter from 'SensorScreen' to 'SensorDetails'. I have tried sending parameters using
NavigationActions.navigate({ routeName: 'sensorDetails' ,params: { sensorType:'Fuel',}});
from 'SensorScreen' class. But was not able to get the parameter in 'SensorDetails' class. How can i pass this params?
A little late answer but might help others that ends up here.
Instead of using NavigationActions you could try navigation from sensorScreen to sensorDetails with navigate and passing some extra variables.
this.props.navigation.navigate('SensorDetails',{sensorType:'Fuel'})
The passed object can then be read in the second screen by
this.props.navigation.state.params.sensorType
A minimal example of the case can be seen in these lines. Observe that this is a stupid on icon tab bar. But it is kept that way since the question was about a tab bar with stacks on each tab. And new tabs are easily added.
import React,{Component} from 'react'
import { Text, View, Footer,Button } from 'react-native'
import {StackNavigator,TabNavigator} from 'react-navigation'
export class SensorScreen extends React.Component {
render() {
return (<Button
onPress={() => this.props.navigation.navigate('SensorDetails',{sensorType:'Fuel'})}
title="Go to Sensor Details"
/>)}}
export class SensorDetails extends React.Component {
render() {
return (<View>
<Text>{this.props.navigation.state.params.sensorType}</Text>
</View>);}
}
const sensorsStack = StackNavigator({
sensors : { screen: SensorScreen },
SensorDetails : { screen: SensorDetails }
});
const MyApp = TabNavigator({
Sensors: {
screen: sensorsStack,
},
});
export default class Nested extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<MyApp/>
);
}
}
Hope this helps.