Passing props in react-native-flux-router - reactjs

So I'm still a bit new to React Native, but I've got an app working nearly how I want it to. I have App.js which uses the TabBarIOS component to display my tabbed navigation at the bottom of the screen. When you touch a tab, the state updates and the relevant content is loaded and displayed:
App.js
import React, { Component } from 'react';
import { TabBarIOS, Platform, Image } from 'react-native';
import IconII from 'react-native-vector-icons/Ionicons';
import IconMCI from 'react-native-vector-icons/MaterialCommunityIcons';
import Colors from './Colors';
import RouterItem1 from './routers/RouterItem1';
import RouterItem2 from './routers/RouterItem2';
import RouterHome from './routers/RouterHome';
import Settings from './components/Settings';
class FooterNav extends Component {
state = {
selectedTab: 'home',
};
handleClick = (routeData) => {
console.log('This has received data', routeData);
this.setState({ selectedTab: routeData });
console.log(this.state);
}
renderCurrentView() {
switch (this.state.selectedTab) {
case 'home':
return (
<RouterHome handleClick={this.handleClick} />
);
case 'item2':
return (
<RouterItem2 />
);
case 'item1':
return (
<RouterItem1 />
);
case 'settings':
return (
<Settings />
);
default:
return false;
}
}
render() {
return (
<TabBarIOS
unselectedTintColor={Colors.third} //Unselected labels
unselectedItemTintColor={Colors.third} //Unselected icons
tintColor={Colors.brandPrimary} //Selected
barTintColor={Colors.light} //Bar background
>
<IconII.TabBarItem
title="Home"
iconName="ios-home-outline"
selectedIconName="ios-home"
selected={this.state.selectedTab === 'home'}
receiveData={this.receiveData}
onPress={() => {
this.setState({
selectedTab: 'home',
});
}}
>
{this.renderCurrentView()}
</IconII.TabBarItem>
<TabBarIOS.Item
icon={require('./images/item2-icon-line#3x.png')}
selectedIcon={require('./images/item2-icon-selected#3x.png')}
title="item2"
selected={this.state.selectedTab === 'item2'}
onPress={() => {
this.setState({
selectedTab: 'item2',
});
}}
>
{this.renderCurrentView()}
</TabBarIOS.Item>
<IconMCI.TabBarItem
title="item1"
iconName="cookie"
selectedIconName="cookie"
selected={this.state.selectedTab === 'item1'}
onPress={() => {
this.setState({
selectedTab: 'item1',
});
}}
>
{this.renderCurrentView()}
</IconMCI.TabBarItem>
<IconII.TabBarItem
title="More"
iconName="ios-more-outline"
selectedIconName="ios-more"
selected={this.state.selectedTab === 'settings'}
onPress={() => {
this.setState({
selectedTab: 'settings',
});
}}
>
{this.renderCurrentView()}
</IconII.TabBarItem>
</TabBarIOS>
);
}
}
module.exports = FooterNav;
react-native-router-flux is a great plugin, once it pulls in a router the flow is exactly what I want it to be. The only problem I have is with the <RouterHome> module:
RouterHome.js
import React from 'react';
import { Scene, Router } from 'react-native-router-flux';
import styles from '../Styles';
import { content } from '../content.js';
import AnotherScene from '../components/pages/AnotherScene';
import Home from '../components/Home';
const RouterHomeComponent = () => {
return (
<Router
sceneStyle={styles.sceneStyle}
navigationBarStyle={styles.navBar}
titleStyle={styles.navBarTitle}
barButtonIconStyle={styles.barButtonIconStyle}
>
<Scene
key="Home"
component={Home}
title={content.heading}
hideNavBar
/>
<Scene
key="AnotherScene"
component={AnotherScene}
title='title'
hideNavBar={false}
/>
</Router>
);
};
export default RouterHomeComponent;
The default view that is loaded is the <Home> module:
Home.js
import React, { Component } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { Actions } from 'react-native-router-flux';
import styles from '../Styles';
import { content } from '../content.js';
class Home extends Component {
displayItem1 = () => {
this.props.handleClick('item1');
}
displayItem2 = () => {
this.props.handleClick('item2');
}
displayAnotherScene() {
Actions.AnotherScene();
}
render() {
return (
<View style={styles.viewWrapperHome}>
<Text style={styles.heading}>{content.greeting}</Text>
<TouchableOpacity onPress={this.displayItem1}>
<Text>First item</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.displayItem2}>
<Text>Second item</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.displayAnotherScene}>
<Text>Another scene</Text>
</TouchableOpacity>
</View>
);
}
}
export default Home;
So what I expect to happen is that if the user clicks on the first two buttons displayed on the screen (First item/Second item), the prop will be passed back to App.js, the state will change and the scene will be updated. It basically is an alternative way of navigating without using the footer menu.
I know that this would work without using the react-native-router-flux module as I had it running before I added it in. The problem is that I really need it to handle the other pages from the <Home> module (many more to add).
Can anyone suggest a way I can pass back the props through the router back to my App.js?

Okay, so I actually figured this out - it turned out to totally be my fault; the props weren't getting passed to RouterHome and so they got lost either side. The new RouterHome looks like this:
RouterHome.js
import React from 'react';
import { Scene, Router } from 'react-native-router-flux';
import styles from '../Styles';
import { content } from '../content.js';
import AnotherScene from '../components/pages/AnotherScene';
import Home from '../components/Home';
const RouterHomeComponent = (props) => { <---Didn't add props
return (
<Router
sceneStyle={styles.sceneStyle}
navigationBarStyle={styles.navBar}
titleStyle={styles.navBarTitle}
barButtonIconStyle={styles.barButtonIconStyle}
>
<Scene
key="Home"
component={Home}
title={content.heading}
hideNavBar
handleClick={props.handleClick} <---Didn't pass props
/>
<Scene
key="AnotherScene"
component={AnotherScene}
title='title'
hideNavBar={false}
/>
</Router>
);
};
export default RouterHomeComponent;
I've marked the two changes I made. Hopefully this will help someone! :)

Related

How to add and remove screens to RAM manually through code in React Native

Problem
I am new to React Native. Recently I faced with such a problem: when I move from the login screen to the signup screen, the signup screen is loaded again each time. How I can load the screen only once and store it in RAM or do something like that, to avoid rerendering? How to add and remove screens to RAM manually through code.
Environment
MacOS 13.0.1 (M1)
React Native CLI
dependencies:
#react-navigation/native: ^6.1.2,
#react-navigation/stack: ^6.3.11,
expo-linear-gradient: ^12.0.1,
react: 18.1.0,
react-native: ^0.70.6,
react-native-color-picker: ^0.6.0,
react-native-event-listeners: ^1.0.7,
react-native-gesture-handler: ^2.9.0,
react-native-localization: ^2.3.1,
react-native-paper: ^5.1.3,
react-native-paper-dropdown: ^1.0.7,
react-native-safe-area-context: ^4.4.1,
react-native-screens: ^3.19.0,
react-native-vector-icons: ^9.2.0,
Code
App.navigator.tsx
import React from "react"
import { createStackNavigator, StackView } from "#react-navigation/stack"
import { NavigationContainer } from "#react-navigation/native"
import { SignupScreen } from "./screens/signup/signup.screen"
import { LoginScreen } from "./screens/login/login.screen"
import { HomeScreen } from "./screens/home/home.screen"
import { SettingsScreen } from "./screens/settings/settings.screen"
const Stack = createStackNavigator()
// App navigation. Used to relocate between the app's screens
const AppNavigator = () => (
<NavigationContainer>
<Stack.Navigator screenOptions={{headerShown: false,
headerMode: "screen",
cardStyle: {backgroundColor: "white"}}}
initialRouteName="Login">
<Stack.Screen name="Login"
component={LoginScreen} />
<Stack.Screen name="SignUp"
component={SignupScreen} />
<Stack.Screen name="Home"
component={HomeScreen} />
<Stack.Screen name="Settings"
component={SettingsScreen} />
</Stack.Navigator>
</NavigationContainer>
)
export default AppNavigator
App.tsx
import React, {useState, useEffect} from 'react';
import {Provider as PaperProvider} from 'react-native-paper';
import { EventRegister } from 'react-native-event-listeners';
import AppNavigator from './app.navigator';
import mainAppTheme, {fontTheme} from './config/theme';
import themeContext from './config/themeContext';
import { CHANGE_THEME_LITERAL } from './config/theme';
const App = () => {
// Theme update
const [theme, setTheme] = useState(mainAppTheme)
useEffect(() => {
let eventListener = EventRegister.addEventListener(CHANGE_THEME_LITERAL, (theme) => {
setTheme(theme)
})
return () => {
EventRegister.removeEventListener(eventListener.toString())
}
})
return (
<themeContext.Provider value={theme}>
<PaperProvider theme={fontTheme}>
<AppNavigator />
</PaperProvider>
</themeContext.Provider>
);
};
export default App;
Login.screen.tsx
import React, { useContext, useState } from "react";
import { SafeAreaView, View } from "react-native";
import { Button, Card, TextInput } from "react-native-paper";
import { PasswordComponent } from "../../components/password.component";
import mainAppTheme, {appTheme} from "../../config/theme";
import themeContext from "../../config/themeContext";
import { loginScreenTrans } from "../../translations/login.screen.trans"
import { loginStyle } from "./login.style";
interface LoignScreenProps{
navigation: any
}
// Login app screen. Meets new users
export const LoginScreen = (props:LoignScreenProps) => {
// Theme update
const theme: appTheme = useContext(themeContext)
loginScreenTrans.setLanguage(theme.lang)
return(
<SafeAreaView style={loginStyle().content}>
<View style={loginStyle().view}>
<Card>
<Card.Title title="BuildIn" titleStyle={loginStyle().cardTitle}></Card.Title>
<Card.Content>
<TextInput selectionColor={theme.colors.mainAppColor}
activeUnderlineColor={theme.colors.mainAppColor}
label={loginScreenTrans.email}
keyboardType="email-address"
style={loginStyle().email} />
<PasswordComponent label={loginScreenTrans.password}
color={theme.colors.mainAppColor.toString()}
style={loginStyle().password}/>
<Button uppercase={false}
textColor={theme.colors.mainAppTextColor}>
{loginScreenTrans.forgot}
</Button>
<Button buttonColor={theme.colors.mainAppColor}
textColor={"#ffffff"}
uppercase={true}
mode="contained"
onPress={() => {props.navigation.navigate("Home");
props.navigation.reset({
index: 0,
routes: [{ name: 'Home' }]})
}}>
{loginScreenTrans.login}
</Button>
<Button uppercase={true}
textColor={mainAppTheme.colors.mainAppTextColor}
onPress={() => props.navigation.navigate("SignUp")}>
{loginScreenTrans.signup}
</Button>
</Card.Content>
</Card>
</View>
</SafeAreaView>
);
}
What i tried
Next steps changed nothing in my case:
Use enableFreeze(true) and enableScreens(true) at the top of loaded screen file and top of navigation file.
Wrap my screen in React.memo()
Set freezeOnBlur: true prop into <Stack.Navigator>
navigation.dispatch(CommonActions.reset({ routes[...]
Maybe I used it incorrectly, I would be grateful if someone could explain to me why.
But it seems that the problem is specifically in the way react navigation works. And I don't know how to set it up the way I want.

React Material UI BottomNavigation component Routing Issue

I'm trying to implement the BottomNavigation Component from Material UI and i have an issue with when the user uses the back and forward buttons of the browser.
The problem is, that the BottomNavigation Component is configured to change page in the the layout when a navigation item button is pressed. What it doesn't do however, is change the selected index of the BottomNavigation items when the browser is used to go back to the previous page.
What im left with is an inconsistent state.
How do i go about changing the selected index of the navigation component when the browser buttons are used?
Here is how the UI looks :-
[
Here is the Root Component :-
import React from 'react'
import {browserHistory, withRouter} from 'react-router';
import {PropTypes} from 'prop-types'
import {connect} from 'react-redux'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import AppBar from 'material-ui/AppBar'
import Paper from 'material-ui/Paper'
import MyBottomNavigation from '../material-ui/MyBottomNavigation'
const style = {
padding: 10,
height: '85vh'
}
class Root extends React.Component {
constructor(props) {
super(props)
this.state = {
bottomNavItemIndex : 0
}
}
render() {
return (
<MuiThemeProvider>
<div>
<AppBar title="Pluralsight Admin"
iconClassNameRight="muidocs-icon-navigation-expand-more"
showMenuIconButton={false}
zDepth={1}
/>
<Paper zDepth={1} style={style}>
{this.props.children}
</Paper>
<MyBottomNavigation/>
</div>
</MuiThemeProvider>
)
}
}
Root.propTypes = {
children: PropTypes.object.isRequired
}
export default Root
And here is the Navigation Component :-
class MyBottomNavigation extends Component {
constructor(props){
super(props)
this.state = {
selectedIndex: 0
}
this.selectBottomNavigationItem = this.selectBottomNavigationItem.bind(this)
}
selectBottomNavigationItem(index){
this.setState({selectedIndex: index})
switch(index) {
case 0:
return browserHistory.push('/')
case 1:
return browserHistory.push('/courses')
case 2:
return browserHistory.push('/authors')
default:
return browserHistory.push('/')
}
}
render() {
return (
<Paper zDepth={1}>
<BottomNavigation selectedIndex={this.state.selectedIndex}>
<BottomNavigationItem
label="Home"
icon={recentsIcon}
onClick={() => this.selectBottomNavigationItem(0)}
/>
<BottomNavigationItem
label="Course"
icon={favoritesIcon}
onClick={() => this.selectBottomNavigationItem(1)}
/>
<BottomNavigationItem
label="Authors"
icon={nearbyIcon}
onClick={() => this.selectBottomNavigationItem(2)}
/>
</BottomNavigation>
</Paper>
)
}
}
export default MyBottomNavigation
Just got an implementation working!
The trick is to make a new navbar component that wraps the Material UI BottomNavigation and exports it with the react-router-dom's withRouter higher order function. Then you can do some fiddling with the current route passed into the props and set the value of the BottomNavigation component based on an array of routes (which route corresponds to which value).
My code works a bit differently than what you posted originally, I'm just going off of the BottomNavigation example here and the example of usage with react-router-dom here.
Here is my implementation:
/src/App.js
import React, {Component} from 'react';
import './App.css';
import {BrowserRouter as Router, Route} from 'react-router-dom';
import PrimaryNav from './components/PrimaryNav';
// Views
import HomeView from './views/HomeView';
class App extends Component {
render() {
return (
<Router>
<div className="app">
<Route path="/" component={HomeView} />
<PrimaryNav />
</div>
</Router>
);
}
}
export default App;
/src/components/PrimaryNav.js
import React, {Component} from 'react';
import {Link, withRouter} from 'react-router-dom';
import BottomNavigation from '#material-ui/core/BottomNavigation';
import BottomNavigationAction from '#material-ui/core/BottomNavigationAction';
import LanguageIcon from '#material-ui/icons/Language';
import GroupIcon from '#material-ui/icons/Group';
import ShoppingBasketIcon from '#material-ui/icons/ShoppingBasket';
import HelpIcon from '#material-ui/icons/Help';
import EmailIcon from '#material-ui/icons/Email';
import './PrimaryNav.css';
class PrimaryNav extends Component {
state = {
value: 0,
pathMap: [
'/panoramas',
'/members',
'/shop',
'/about',
'/subscribe'
]
};
componentWillReceiveProps(newProps) {
const {pathname} = newProps.location;
const {pathMap} = this.state;
const value = pathMap.indexOf(pathname);
if (value > -1) {
this.setState({
value
});
}
}
handleChange = (event, value) => {
this.setState({ value });
};
render() {
const {value, pathMap} = this.state;
return (
<BottomNavigation
value={value}
onChange={this.handleChange}
showLabels
className="nav primary"
>
<BottomNavigationAction label="Panoramas" icon={<LanguageIcon />} component={Link} to={pathMap[0]} />
<BottomNavigationAction label="Members" icon={<GroupIcon />} component={Link} to={pathMap[1]} />
<BottomNavigationAction label="Shop" icon={<ShoppingBasketIcon />} component={Link} to={pathMap[2]} />
<BottomNavigationAction label="About" icon={<HelpIcon />} component={Link} to={pathMap[3]} />
<BottomNavigationAction label="Subscribe" icon={<EmailIcon />} component={Link} to={pathMap[4]} />
</BottomNavigation>
);
}
}
export default withRouter(PrimaryNav);
And here's my version numbers for good measure:
"#material-ui/core": "^1.3.1",
"#material-ui/icons": "^1.1.0",
"react": "^16.4.1",
"react-dom": "^16.4.1",
Just found a really neat solution for this here:
Essentially you just create a pathname constant each render, using window.location.pathname and make sure that the value prop of each <BottomNavigationAction /> is set to the same as the route (including preceding forward slash) ...something like:
const pathname = window.location.pathname
const [value, setValue] = useState(pathname)
const onChange = (event, newValue) => {
setValue(newValue);
}
return (
<BottomNavigation className={classes.navbar} value={value} onChange={onChange}>
<BottomNavigationAction component={Link} to={'/'} value={'/'} label={'Home'} icon={<Home/>} />
<BottomNavigationAction component={Link} to={'/another-route'} value={'/another-route'} label={'Favourites'} icon={<Favorite/>} />
</BottomNavigation>
)
This means the initial state for value is always taken from the current URL.
I think you should avoid internal state management for this component. If you need to know and highlight the current selected route, you can just use NavigationLink from react-router-dom instead of Link. An "active" class will be added to the corresponding element. You just need to pay attention for the exact prop if you want the navigation element to be active only when an exact match is detected.
[Update] I wrote the wrong component name that is NavLink, not NavigationLink. My bad. Here is the link to the doc https://reactrouter.com/web/api/NavLink

react-native, how to factorize code over many tabs

I use react-native to create ios and android app
I create a test app with TabNavigator working good plus a sidemenu ( the button to open it should be in the top action bar ) and floatings actions buttons (the red circle labeled FAB on the picture). All this code is new defined on first tab : app.js.
Each tab have it's own js file with code and render.
My question is :
How to get this sidemenu,action bar and floating buttons on ALL tabs without coping all the render code and js functions over all the other tabs Js files.
when i click on a tab only the green part will change
my App.js
import React, { Component } from "react";
import {...} from "react-native";
import { TabNavigator } from "react-navigation";
import Imagetest from "./Photo";
import ListFlatlist from "./ListFlatlist";
... // importing the other file for the tabs
import styles from "./css/styles";
import SideMenu from "react-native-side-menu";
import Menu from "./Menu";
class App extends Component {
constructor(props) { ... }
...
render() {
const menu = <Menu onItemSelected={this.onMenuItemSelected} />;
return (
<SideMenu
menu={menu}
isOpen={this.state.isOpen}
onChange={isOpen => this.updateMenuState(isOpen)}
>
<View style={styles.container}>
{/* my app.js content
*/}
// this is floating buttons
<ActionButton buttonColor="rgba(231,76,60,1)">
<ActionButton.Item buttonColor='#9b59b6' title="New Task" onPress={() => console.log("notes tapped!")}>
<Icon name="md-create" style={styles.actionButtonIcon} />
</ActionButton.Item>
</ActionButton>
</View>
</SideMenu>
);
}
}
const AppNavigator = TabNavigator(
{
H: { screen: App },
f: { screen: ListFlatlist },
Img: { screen: Imagetest },
B: { screen: Buttonpage },
S: { screen: ListSectionlist },
F: { screen: Fetchpage }
}
);
export default AppNavigator;
If a create new components for sidemenu, action bar and FAB I have to put them on all the tab render, not the cleanest way for me but i don't see other solution now.
I put an example repo together on Github. Thats actually all it needs:
// #flow
import React, { Component } from "react";
import { View } from "react-native";
import { StackNavigator, TabNavigator } from "react-navigation";
import ActionButton from "react-native-action-button";
import Profile from "./Profile";
import Tab1View from "./Tab1";
import Tab2View from "./Tab2";
import Tab3View from "./Tab3";
const TabView = TabNavigator({
tab1: { screen: Tab1View },
tab2: { screen: Tab2View },
tab3: { screen: Tab3View },
})
const Home = (props) => {
return (
<View style={{flex: 1}}>
<TabView navigation={props.navigation} />
<ActionButton offsetY={100} />
</View>
);
}
Home.router = TabView.router;
const StackView = StackNavigator({
home: { screen: Home },
profile: { screen: Profile },
});
export default class App extends Component {
render() {
return (
<View style={{ flex: 1 }}>
<StackView />
</View>
);
}
}

React Native trying to change the required image based on title

what I am trying to do is create a dynamic function to change the required image based on what the title is.
I have tried if statements with no success, though i am still new to react native, and i believe switch cases are hard if not possible in this case, but i have left it up there to help show my point.
What I wanted to do is the title of the tab that is passed in and see if its matched with one of the three, if it is, then i set the required image to a var icon and put that into a return image.
it will come back with no errors, but no images, any ideas are appreciated.
import React from 'react';
import styles from './styling/style.js';
import {StyleSheet, Text, Image, View} from 'react-native';
import {Router, Scene } from 'react-native-router-flux';
import Homepage from './homepage.js';
import Workout from './workouts';
import Settings from './settings';
const TabIcon = ({ selected, title}) => {
switch ({title}) {
case Homepage:
var icon = require("./images/tabHomePageIcon.png");
break;
case Workout:
var icon = require("./images/tabWorkoutIcon.png");
break;
case Settings:
var icon = require("./images/tabSettingIcon.png");
break;
}
return (
<View>
<Image source={icon}></Image>
<Text>{title}</Text>
</View>
);
};
const UniversalTitle = ({selected, title}) => {
return (
<Text style={styles.text}>
Ultimate Fitness Tracker {'\n'}
<Text style={styles.textBody}>The most comprehensive tracker available!
</Text>
</Text>
)
};
export default class Index extends React.Component {
render() {
return (
<Router>
<Scene key='root'>
<Scene key='tabbar' tabs tabBarStyle={styles.footer}>
<Scene key='tabHome' title='Homepage' titleStyle={styles.text} icon={TabIcon}>
<Scene key='pageOne' navigationBarStyle={styles.heading} component={Homepage} renderTitle={UniversalTitle} initial />
</Scene>
<Scene key='tabWorkout' titleStyle={styles.text} title='Workout' icon={TabIcon}>
<Scene key='pageTwo' component={Workout} navigationBarStyle={styles.heading} renderTitle={UniversalTitle} />
</Scene>
<Scene key='tabSettings' titleStyle={styles.text} title='Setting' icon={TabIcon}>
<Scene key='pageThree' component={Settings} navigationBarStyle={styles.heading} renderTitle={UniversalTitle} />
</Scene>
</Scene>
</Scene>
</Router>
)
}
}
In TabIcon Component, you have written
switch ({title})
It should be
switch (title)
and declare variable icon before switch statement.
Try this.
const TabIcon = ({ selected, title}) => {
let icon
switch (title) {
case Homepage:
icon = require("./images/tabHomePageIcon.png");
break;
case Workout:
icon = require("./images/tabWorkoutIcon.png");
break;
case Settings:
icon = require("./images/tabSettingIcon.png");
break;
}
return (
<View>
{icon && <Image source={icon}></Image>}
<Text>{title}</Text>
</View>
);
};
Hope, it solves your problem.

React Native's Navigator is not working

Navigator is not working, it's empty.I'm getting a blank page, Home component is not showing up. I tried other components and got the same result.
Addding this so I can post the question
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
import React, { Component } from 'react';
import {
AppRegistry,
View,
Text,
StyleSheet,
Navigator
} from 'react-native';
import Login from './components/Login';
import Home from './components/Home';
import LoginForm from './components/LoginForm';
export default class App extends Component {
renderScene(route, navigator) {
console.log(route);
if(route.name == 'login') {
return <Login navigator={navigator} />
}
if(route.name == 'home') {
return <Home navigator={navigator} />
}
}
render() {
return (
<View style={styles.container}>
<Navigator
initialRoute={{name: 'home'}}
renderScene={this.renderScene.bind(this)}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#4fb0c9',
}
});
I haven't tested your code but I can see you didn't use renderScene() in the right way. What I suggest is to move your routes out of App.js file and create a routes.js in this way so you are avoiding to have lots of if for your routes:
Route.js
import LoginView from './LoginView';
import HomeView from './HomeView';
let routes = {
HomeView: {
name: 'HomeView',
component: HomeView,
index: 0
},
LoginView: {
name: 'LoginView',
component: LoginView,
index: 1,
sceneConfig: Navigator.SceneConfigs.PushFromRight //you can change your view transitions here
},
};
export default Routes;
And in your app.js file you have to
import Routes from './routes';
And update render()
render(){
<Navigator
initialRoute={Routes.HomeView}
sceneStyle={styles.container}
renderScene={(route, navigator) => {
const Component = route.component;
return <Component
navigator={navigator} //pass it down to each view so it can be called
route={route}
/>
}}
configureScene={(route) => {
if (route.sceneConfig) {
return route.sceneConfig;
}
return Navigator.SceneConfigs.FadeAndroid;
}}
/>
}
Hope it helps you out.
Sample code for navigator
import SplashScreen from './SplashScreen';
class AppContainer extends Component {
render() {
return (
<Navigator
initialRoute={{ id: 'SplashScreen', name: 'Index' }}
renderScene={this.renderScene.bind(this)}
configureScene={(route, routeStack) => Navigator.SceneConfigs.FloatFromRight}
/>
);
}
renderScene = (route, navigator) => {
if (route.id === 'SplashScreen') {
return (
<SplashScreen
navigator={navigator}
/>
);
}
}
}
We get navigator as props in components when we are passing navigator in splashScreen.

Resources