rerender component when tab is choosed react-native - reactjs

I'm using TabNavigator from react-navigation to navigate through 3 component. My TabNavigator component look like this:
import routeOnMap from '../screens/routsOnMap.js';
import meditatinWalk from '../screens/meditationWalk.js';
import newWordToWalkOn from '../screens/newWordToWalkOn.js';
import * as firebase from 'firebase';
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
Button
} from 'react-native';
import {
StackNavigator,
NavigationActions,
TabNavigator,
TabBarBottom,
} from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
export default TabNavigator(
{
MeditatinWalk: { screen: meditatinWalk },
NewWordToWalkOn: { screen: newWordToWalkOn },
RouteOnMap: { screen: routeOnMap },
},
{
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
let iconName;
if (routeName === 'MeditatinWalk') {
iconName = `ios-walk${focused ? '' : '-outline'}`;
} else if (routeName === 'NewWordToWalkOn') {
iconName = `ios-add-circle${focused ? '' : '-outline'}`;
} else if (routeName === 'RouteOnMap') {
iconName = `ios-map${focused ? '' : '-outline'}`;
}
// You can return any component that you like here! We usually use an
// icon component from react-native-vector-icons
return <Ionicons name={iconName} size={25} color={tintColor} />;
},
}),
tabBarOptions: {
activeTintColor: '#626A41',
inactiveTintColor: 'gray',
},
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false,
}
);
I want to rerender whats inside my NewWordToWalkOn component when it's when it is pressed/tabbed. The code I would like to rerender is whats inside the componentDidMount() methode in the NewWordToWalkOn component.
//imports
export default class NewWordToWalkOn extends Component {
constructor() {
super()
this.state = {
words: [],
};
}
static navigationOptions = ({ navigation }) => ({
title:
<Text style={{ fontWeight: 'bold', color: '#626A41'}}> Vælg nye ord at vandre på </Text>,
headerLeft: null,
headerRight:
<TouchableOpacity
style={{ flex: 1, alignItems: 'center', justifyContent: 'center', marginRight: 10 }}
onPress={ () => MeditatinWalk._logout() }>
<Text
style={{ fontWeight: 'bold', color: '#626A41'}}>
Log ud
</Text>
</TouchableOpacity>
});
componentDidMount() {
//code that needs rerendered
}
render() {
)
return (
<ScrollView style={styles.wrapper}>
//all the elements
</ScrollView>
);
}
}
Any suggestions how to rerender?

If you want to update your view when the tab is pressed, try subscribe navigation lifecycle event with this.props.navigation.addListener.
Example:
class NewWordToWalkOn extends Component {
constructor (props) {
super(props)
this.navigationWillFocusListener = props.navigation.addListener('willFocus', () => {
// do something like this.setState() to update your view
})
}
componentWillUnmount () {
this.navigationWillFocusListener.remove()
}
}

Related

Flat List navigation react native

I been having an issue with navigating from API flat list to separate screen. I got a news api integrated and I want to from each article render to navigate to newsdetail screen. I'm not getting an error message only touchable opacity is not working. I'm not sure where I made a mistake in the flatlist or in the APP.js
FlatList:
import React, { Component } from 'react';
import { FlatList, TouchableOpacity } from 'react-native';
import { getUSANews } from './fetchNews';
import Article from './Article';
import NewsDetail from '../screens/NewsDetail';
class News extends Component {
state = {
articles: [],
refreshing: true
};
componentDidMount = () => {
this.fetchNews();
};
fetchNews = () => {
getUSANews()
.then(articles => {
this.setState({ articles, refreshing: false });
})
.catch(() => this.setState({ refreshing: false }));
};
handleRefresh = () => {
this.setState({ refreshing: true }, () => this.fetchNews());
};
render(navigation) {
return (
<FlatList
data={this.state.articles}
keyExtractor={item => item.url}
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh}
renderItem ={({item}) => {
return (
<TouchableOpacity onPress={() => this.props.navigation.navigate('NewsDetail')}
>
<Article article={item} />
</TouchableOpacity>
);
}}
/>
);
}
}
export default News;
App.js:
const Drawer = createDrawerNavigator(
{
Home: {
screen: homeScreen,
Options: {
title: 'Home',
activeTintColor: 'red'
},
},
Signin:{
screen: SigninScreen,
Options: {
title: "Sign In",
},
},
Signup: {
screen: SignupScreen,
navigationOptions: {
title: 'Sign Up'
}
}
},
{
initialRouteName: 'Home',
unmountInactiveRoutes: true,
headerMode: 'none',
contentOptions: {
activeTintColor: 'red'
},
},
);
const AppNavigator = createStackNavigator({
Drawer: {
screen: Drawer,
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Home",
headerTitleStyle: {
color: "white"
},
headerStyle: {
backgroundColor: "#5BBC9D"
},
headerLeft: (
<Icon
onPress={() => navigation.openDrawer()}
name="md-menu"
color="white"
size={30}
style={{
paddingLeft: 10
}}
/>
),
headerRight: (
<Icon
onPress={() => navigation.se()}
name="ios-search"
color="white"
size={30}
style={{
paddingRight: 10
}}
/>
)
}
}},
Detail: {
screen:NewsDetail
}
})
const AppContainer = createAppContainer(AppNavigator);
export default class App extends React.Component {
render (){
return(
<AppContainer />
);
}
}
You don't have any screen name NewsDetail change this:
onPress={() => this.props.navigation.navigate('NewsDetail')}
to
onPress={() => this.props.navigation.navigate('Detail')}
Hope this helps!
You set the RouteName to your newsDetail screen as Detail. Hence to navigate to that screen you need to use the RouteName you set and not the screen name. Kindly change from;
onPress={() => this.props.navigation.navigate('NewsDetail')}
to
onPress={() => this.props.navigation.navigate('Detail')}

How to navigate between screens without adding it to tabNavigation in react native

Suppose you have a react native app that has a flow that navigates between screens upon data entry, how would you navigate through these screens without having to add these screens to a stackNavigation or createbottomtabnavigator?
For example here is my app upon being on home page.
1)
2)
3) It gets added to navigation tab menu :(
here is the navigation code.
import React from "react";
// import HomeView from "./components/screens/Home";
import AddPostView from "./containers/addPost";
import SettingsView from "./containers/settings";
import ContentView from "./components/screens/AddContent";
import Icon from "react-native-vector-icons/AntDesign";
import { createAppContainer } from "react-navigation";
import DashboardView from "./components/screens/Dashboard";
import { createMaterialBottomTabNavigator } from "react-navigation-material-bottom-tabs";
const AppNavigator = createMaterialBottomTabNavigator(
{
Home: {
screen: AddPostView, // shows the title screen is there a way i can nest the screens apart of this screen ?
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="home" color={tintColor} size={24} />
)
}
},
Content: {
screen: ContentView, // shows add content screen.
labeled: false,
navigationOptions: {
tabBarIcon: false,
tabBarLabel: false
}
},
Dashboard: {
screen: DashboardView,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="dashboard" color={tintColor} size={24} />
)
}
},
Settings: {
screen: SettingsView,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="user" color={tintColor} size={24} />
)
}
}
},
{
initialRouteName: "Home",
activeColor: "#f0edf6",
tabBarLabel: "Content",
inactiveColor: "#333333",
barStyle: {
backgroundColor: "#B9D2B1",
justifyContent: "center",
alignItems: "center"
}
}
);
export default createAppContainer(AppNavigator);
AddPost.jsx
import React, { Component, Fragment } from "react";
import { View, Text, Button, StyleSheet } from "react-native";
import { Subheading, Dialog } from "react-native-paper";
import PostForm from "../forms/createPost/createPost";
export default class AddPostView extends Component {
state = {
title: "",
content: "",
touched: {
title: false,
content: false
}
};
titleChange = title => {
this.setState({ title });
};
validate = field => {
console.log("tet", field);
this.setState({
touched: { ...this.state.touched, [field]: true }
});
console.log(this.state.touched);
};
contentChange = content => {
this.setState({ content });
};
render() {
const isEnabled = this.state.title.length > 6 ? false : true;
return (
<Fragment>
<Subheading style={styles.labels}> Add An Entry</Subheading>
<PostForm
title={this.state.title}
titleChange={this.titleChange}
disButton={isEnabled}
hasError={this.state.touched}
onSubmit={() => this.props.navigation.navigate("Content")}
validateTitle={() => this.validate("title")}
/>
</Fragment>
);
}
}
const styles = StyleSheet.create({
labels: {
textAlign: "center",
fontWeight: "bold",
fontSize: 25,
padding: 20,
marginTop: 50
}
});
I found a way to do this. Here were my steps
1) Create a new file called otherNav.jsx (this can handle multiple screens for different scenarios, for now i just need it to navigation to a form)
import React from "react";
import { createStackNavigator } from "react-navigation-stack";
import { createAppContainer } from "react-navigation";
import ContentView from "./containers/addContent";
import Icon from "react-native-vector-icons/AntDesign";
const OtherNavigation = createStackNavigator(
{
Content: {
screen: ContentView
}
},
{
headerMode: "none",
activeColor: "#f0edf6",
tabBarLabel: "Content",
inactiveColor: "#333333",
barStyle: {
backgroundColor: "#B9D2B1",
justifyContent: "center",
alignItems: "center"
}
}
);
export default createAppContainer(OtherNavigation);
2) Call this in AuthNav where all the navigations live
import React, { Component } from "react";
import { createAppContainer } from "react-navigation";
import AuthLoadingScreen from "./AuthLoadingScreen";
import AuthNavigation from "./splashNav";
import AppNavigator from "./loggedInNav";
import OtherNavigation from "./otherNav";
import { createStackNavigator } from "react-navigation-stack";
export default createAppContainer(
createStackNavigator(
{
AuthLoading: {
screen: AuthLoadingScreen // intimidiary between App && Auth checks for token and such
},
App: AppNavigator,
Content: OtherNavigation,
Auth: AuthNavigation
},
{
initialRouteName: "AuthLoading",
headerMode: "none"
}
)
);
3) Now this will flow accordingly
render() {
const isEnabled = this.state.title.length > 6 ? false : true;
return (
<Fragment>
<Subheading style={styles.labels}> Add An Entry</Subheading>
<PostForm
title={this.state.title}
titleChange={this.titleChange}
disButton={isEnabled}
hasError={this.state.touched}
onSubmit={() => this.props.navigation.navigate("Content")}
validateTitle={() => this.validate("title")}
/>
</Fragment>
);
}
}
So now we have this (end result its not added to bottomNav)
1)
2)

Simple Styling with React Native

I am trying to create a basic app that navigates pages, but for some reason my react native code isn't including the styling. In the view, I clearly state that it should use the styles.container, but it doesn't respond. I tried to use the same styling code from the tutorial, but whenever I change any of the elements, even just the color, the button doesn't change. When I have a Text element instead, it still doesn't change. What am I doing wrong?
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import Expo from 'expo';
import { createStackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
};
render() {
const{ navigate } = this.props.navigation;
return (
<View stlye={styles.container}>
<Button
style={styles.container}
title="Go to the profile screen."
onPress = { () =>
navigate('Profile')
}
/>
</View>
);
}
}
class ProfileScreen extends React.Component {
static navigationOptions = {
title: 'Profile',
};
render() {
const{ navigate } = this.props.navigation;
return (
<View stlye={styles.container}>
<Button
style={styles.container}
title="Go to the home screen."
onPress = { () =>
navigate('Home')
}
/>
</View>
);
}
}
const NavigationApp = createStackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
}, {
navigationOptions: {
headerStyle: {
marginTop: Expo.Constants.statusBarHeight
}
}
});
export default class App extends React.Component {
render() {
return <NavigationApp />;
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
You are setting up stlye instead of style in <View.
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import Expo from 'expo';
import { createStackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
};
render() {
const{ navigate } = this.props.navigation;
return (
<View style={styles.container}>
<Button
style={styles.container}
title="Go to the profile screen."
onPress = { () =>
navigate('Profile')
}
/>
</View>
);
}
}
class ProfileScreen extends React.Component {
static navigationOptions = {
title: 'Profile',
};
render() {
const{ navigate } = this.props.navigation;
return (
<View style={styles.container}>
<Button
style={styles.container}
title="Go to the home screen."
onPress = { () =>
navigate('Home')
}
/>
</View>
);
}
}
const NavigationApp = createStackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
}, {
navigationOptions: {
headerStyle: {
marginTop: Expo.Constants.statusBarHeight
}
}
});
export default class App extends React.Component {
render() {
return <NavigationApp />;
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
It could be due to this typo in your code :
<View stlye={styles.container}>

React Navigation failed. No errors

I'm trying to navigate from tab page to other page. I'm following tabnavigator and stacknavigator.
myTabsHost(RegisterHostPage) Here I'm hosting two tabs
import React, { Component } from "react";
import {
AppRegistry,
Text,
View,
Image,
StyleSheet,
TouchableOpacity
} from "react-native";
import { TabNavigator } from "react-navigation";
import { Tab } from "../../config/router.js";
import {Tab2} from "../../config/router.js";
import { NavigationActions } from "react-navigation";
class RegisterHost extends Component {
render() {
return (
<View style={Styles.container}>
<Text style={Styles.boldLabel}> User Register</Text>
<Text style={Styles.normalLabel}>Wallet account registration</Text>
<TouchableOpacity
onPress={() => {
const navigateAction = NavigationActions.navigate({
key: null,
routeName: "preactivate",
params: {}
});
this.props.navigation.dispatch(navigateAction);
}}
>
<Text>topreactivate</Text>
</TouchableOpacity>
<Tab2 />
</View>
);
}
}
const Styles = StyleSheet.create({
container: {
flex: 1,
padding: 2,
justifyContent: "center",
backgroundColor: "#FFFFFF"
},
boldLabel: {
fontWeight: "bold",
fontSize: 24,
alignSelf: "center",
color: "#08AE9E",
marginBottom: 20,
marginTop: 10
},
normalLabel: {
fontWeight: "normal",
fontSize: 18,
alignSelf: "center",
color: "black",
marginBottom: 20,
marginTop: 10
}
});
export default RegisterHost;
myTabPage (BankCustomerRegister)
import React, { Component } from "react";
import {
Text,
View,
Image,
StyleSheet,
TextInput,
TouchableOpacity
} from "react-native";
import { TabNavigator } from "react-navigation";
import{StackNavigator} from 'react-navigation';
import FetchData from "../../utils/fetch.js";
class BankCustomerRegister extends Component {
constructor(props) {
super(props);
this.state = {
stCustId: "",
stIdcard: "",
stPhoneNum: "",
isMounted: false
};
}
}
};
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<Image source={require("../../resources/icons/bank.png")} />
<TextInput
style={styles.textInput}
onChangeText={this._handleCustId}
placeholderTextColor="black"
placeholder="Customer ID"
/>
<TextInput
style={styles.textInput}
placeholderTextColor="black"
onChangeText={this._handleIdCard}
placeholder="ID card"
/>
<TextInput
style={styles.textInput}
placeholderTextColor="black"
onChangeText={this._handlePhoneNum}
placeholder="Phone No"
/>
<TouchableOpacity
onPress={() => {
// NOTICE HERE
const navigateAction = NavigationActions.navigate({
routeName: "preactivate",
params: {},
});
this.props.navigation.dispatch(navigateAction);
}}
style={styles.touchable}
>
<Text style={styles.btnlabel}>Register</Text>
</TouchableOpacity>
</View>
);
}
}
export default BankCustomerRegister;
when i click touchable.its supposed to navigate to otherPage, i'ts not navigating anywhere , even no errors.
myOtherPage(preactivate)
import React, { Component } from "react";
import {
View,
Text,
StyleSheet
} from "react-native";
class PreUserActivation extends Component {
// Render callBack
render() {
return (
<View style={styles.container}>
<Text>Screen</Text>
</View>
);
}
}
export default PreUserActivation;
My router config in router.js
//tab Router
export const Tab = TabNavigator(
{
BankCustomerRegister: {
screen: BankCustomerRegister,
navigationOptions: {
tabBarLabel: "Bank Customer"
}
},
nonbankcustomer: {
screen: NonCustomerRegister,
navigationOptions: {
tabBarLabel: "New Customer"
}
}
},
{
tabBarPosition: "top",
animationEnabled: true,
tabBarOptions: {
// activeTintColor: "#e91e63",
labelStyle: {
fontSize: 16
},
style: {
backgroundColor: "#08AE9E"
},
tabStyle: { width: 200 } //Set width to make INLINE TABS
}
}
);
export const Root = StackNavigator({
board: {
screen: OnBoardScreen,
navigationOptions: {
header: null
}
},
preactivate: {
screen: PreUserActivation,
navigationOptions: {
header: null
}
},
Tabs: {
screen: Tab
}
});
Is there something i'm missing.
You need a reset. Use navigate() when navigating from one tab to another in the same TabNavigator for example. In your case, you are navigating to a screen in the parent navigator. Try this instead:
onPress={() => {
const navigateAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'preactivate'})
]
});
this.props.navigation.dispatch(navigateAction);
}}

How to resolve React-Native navigation error for undefined is not an object?

Here's my code. I have tried many different things based on react-navigation and navigators but still getting Undefined is not an object(evaluating _this3.props.navigation.navigate).
I even tried restarting the package manager and running project again.
I am running my project on Android Device.
Please help with relevant lines to my code.
import React, {
Component
} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
Button,
Alert,
} from 'react-native';
import {
StackNavigator,
} from 'react-navigation';
import ProfileScreen from './ProfileScreen'
//import HomeScreen from './HomeScreen'
export const AwesomeProject = StackNavigator({
//Home: {screen: HomeScreen},
Profile: {
screen: ProfileScreen,
navigationOptions : {
title: 'Welcome',
}
},
});
const onButtonPress = () => {
Alert.alert('Button has been pressed!');
};
class Blink extends Component {
constructor(props) {
super(props);
this.state = {
showText: true
};
// Toggle the state every second
setInterval(() => {
this.setState({
showText: !this.state.showText
});
}, 1000);
}
render() {
let display = this.state.showText ? this.props.text : ' ';
return (
<Text> {display} </Text>
);
}
}
export default class HomeScreen extends Component {
constructor(props){
super(props)
}
render() {
//const {navigate} = this.props.navigation;
return (
<View style={styles.container}>
<Text style={styles.welcome}>
<Blink text='Hello!'/>
</Text>
<Button
//onPress = {onButtonPress}
onPress = {() => this.props.navigation.navigate('Profile').bind(this)}
title="Lets Go!"
color="#851884"
accessibilityLabel="Learn more about people">
</Button>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#456987',
},
welcome: {
fontSize: 20,
textAlign: 'center',
color: '#DD5522',
margin: 10,
},
});

Resources