Re Render Tab Navigator onPress React Navigation - react-native

when i'm using stack navigator only. the screen get re render every time when i navigate to another screen. so how to do the same thing with tab navigator? every time i press the tab menu(favorite)?
Screenshot:
Code:
const RootStack = StackNavigator(
{
Home: {
screen: Home,
navigationOptions: {
header: null
}
},
Menu: {
screen: Menu,
navigationOptions: {
header: null
}
},
}
);
export default TabNavigator(
{
Home: { screen: RootStack },
Favorite: { screen: Favorite },
},
{
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
let iconName;
if (routeName === 'Home') {
iconName = `home`;
} else if (routeName === 'Favorite') {
iconName = `heart`;
}
return <Icon name={iconName} size={25} color={tintColor} />;
},
}),
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
tabBarOptions: {
activeTintColor: '#00a6ed',
inactiveTintColor: '#9e9e9e',
style: {
backgroundColor: '#FFFFFF',
},
},
animationEnabled: false,
swipeEnabled: false,
}
);
Thanks in advance!

There are 2 different ways I found below,
// call when the screen is focused
componentDidMount () {
this._navListener = this.props.navigation.addListener('didFocus', (payload) => {
// update based on your requirements
});
}
OR
import { NavigationEvents } from "react-navigation";
...
class HomeScreen extends React.Component {
render() {
return (
<View>
<NavigationEvents
onWillFocus={() => {
// update based on your requirements!
}}
/>
<Text>Home</Text>
</View>
);
}
}

I recommend using Hooks to re-render for the screen when it changes focus, The library exports a useIsFocused hook to make this easier
isFocused is method lets us check whether the screen is currently focused. Returns true if the screen is focused and false otherwise.
import { useIsFocused } from '#react-navigation/native';
import { Text } from '#react-native';
function Home() {
const isFocused = useIsFocused();
return <Text>{isFocused ? 'focused' : 'unfocused'}</Text>;
}
If you are using class component you can wrap your class component in a function component
import { useIsFocused } from '#react-navigation/native';
class Home extends React.Component {
render() {
// Get it from props
const { isFocused } = this.props;
}
}
// Wrap and export
export default function(props) {
const isFocused = useIsFocused();
return <Home {...props} isFocused={isFocused} />;
}

react-navigation supports listeners which you can use to detect focus or blur state of screen.
addListener - Subscribe to updates to navigation lifecycle
React Navigation emits events to screen components that subscribe to
them:
willBlur - the screen will be unfocused
willFocus - the screen will focus
didFocus - the screen focused (if there was a transition, the transition completed)
didBlur - the screen unfocused (if there was a transition, the transition completed)
Example from the docs
const didBlurSubscription = this.props.navigation.addListener(
'didBlur',
payload => {
console.debug('didBlur', payload);
}
);
// Remove the listener when you are done
didBlurSubscription.remove();
// Payload
{
action: { type: 'Navigation/COMPLETE_TRANSITION', key: 'StackRouterRoot' },
context: 'id-1518521010538-2:Navigation/COMPLETE_TRANSITION_Root',
lastState: undefined,
state: undefined,
type: 'didBlur',
};

Related

createBottomTabNavigator white space (icon is auto hide) when keyboard show

React-native application with version:
react#16.9.0
react-native#0.61.2
react-navigation#^4.0.10
react-navigation-stack#^1.10.3
react-navigation-tabs#^2.5.6
I'm trying to make an application with createBottomTabs, when i try to type in TextInput, when the keyboard show, there are bottomtabs with icon, the icon will auto hide, leaving the white space / gap behind on top of the keyboard
my code example :
<SafeAreaView style={
flex: 1,
alignItems: 'center'
}>
<View>
<TextInput />
</View>
</SafeAreaView>
already tried to change SafeAreaView with KeyboardAvoidingView, but the white space/gap is still there.
const MainTabs = createBottomTabNavigator({
Screen1: {
screen: Screen1Stack,
navigationOptions: {
tabBarIcon: Icon
}
},
Screen2: {
screen: Screen2Screen,
navigationOptions: {
tabBarIcon: Icon
}
},
Screen3: {
screen: Screen3Screen,
navigationOptions: {
tabBarIcon: Icon
}
},
Screen4: {
screen: Screen4Screen,
navigationOptions: {
tabBarIcon: Icon
}
},
},
{
tabBarOptions: {
...
showLabel: false
}
}
)
i get the answer from the comment at react navigation tabs github (with title "Bottom tab bars and keyboard on Android #16"), and i will share it here, incase someone experiencing a same issue as me, its answered by #export-mike and detailed by #hegelstad
import React from 'react';
import { Platform, Keyboard } from 'react-native';
import { BottomTabBar } from 'react-navigation-tabs'; // need version 2.0 react-navigation of course... it comes preinstalled as a dependency of react-navigation.
export default class TabBarComponent extends React.Component {
state = {
visible: true
}
componentDidMount() {
if (Platform.OS === 'android') {
this.keyboardEventListeners = [
Keyboard.addListener('keyboardDidShow', this.visible(false)),
Keyboard.addListener('keyboardDidHide', this.visible(true))
];
}
}
componentWillUnmount() {
this.keyboardEventListeners && this.keyboardEventListeners.forEach((eventListener) => eventListener.remove());
}
visible = visible => () => this.setState({visible});
render() {
if (!this.state.visible) {
return null;
} else {
return (
<BottomTabBar {...this.props} />
);
}
}
}
Usage :
const Tabs = createBottomTabNavigator({
TabA: {
screen: TabA,
path: 'tab-a',
navigationOptions: ({ navigation }) => ({
tabBarLabel: 'Tab A',
})
},
TabB: {
screen: TabB,
path: 'tab-b',
navigationOptions: ({ navigation }) => ({
tabBarLabel: 'Tab B',
})
}
},
(Platform.OS === 'android')
? {
tabBarComponent: props => <TabBarComponent {...props} />,
tabBarPosition: 'bottom'
}
: {
// don't change tabBarComponent here - it works on iOS after all.
}
);

react navigation - DrawerNavigator for Header Menu icon inside TabNavigator-> StackNavigator

I want to display HeaderLeft Menu icon globally in all screens. When I click on Menu Icon, I need to display Drawer Menu. I use "OpenDrawer", "CloseDrawer" methods for open/close drawer menu.
But I am always getting "undefined is not a function (evaluating 'props.navigation.openDrawer()')". I also tried the following
props.navigation.dispatch(DrawerActions.openDrawer())
props.navigation.navigate(openDrawer())
But None of the above worked. Here is my partial code
const MenuButton = (props) => {
return (
<View>
<TouchableOpacity onPress={() => { props.navigation.dispatch(DrawerActions.openDrawer())} }>
<Text>Menu</Text>
</TouchableOpacity>
</View>
)
};
const MyDrawerNavigator = createDrawerNavigator(
{
Wishist: {
screen: wishlist
},
},
{
contentComponent: SideMenuScreen,
drawerWidth: 200,
}
);
const AppNavigator = createBottomTabNavigator({
Home: {
screen: createStackNavigator({
Home: {
screen: Home
},
Contact: {
screen: Contact
}
},
{
defaultNavigationOptions: ({ navigation }) => ({
headerStyle: {
backgroundColor: 'white',
borderWidth:0,
borderBottomWidth:0
},
headerTitle: headerTitleNavigationOptions('HOME'),
headerLeft: <MenuButton navigation={navigation}/>,
headerRight: headerRightNavigatorOptions(navigation)
})
}),
navigationOptions: ({ navigation }) => ({
headerStyle: {
backgroundColor: 'white',
borderWidth:0,
borderBottomWidth:0
},
}),
}},
{
tabBarOptions: {
showLabel: false,
style: {
backgroundColor: 'white',
borderTopWidth:1
}
},
initialRouteName: 'Home',
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false
}
);
const App = createAppContainer(AppNavigator);
you need to import the DrawerActions in your component from react-navigation-drawer as explained in the docs
DrawerActions is an object containing methods for generating actions specific to drawer-based navigators. Its methods expand upon the actions available in NavigationActions.
The following actions are supported:
openDrawer - open the drawer
closeDrawer - close the drawer
toggleDrawer - toggle the state, ie. switche from closed to open and
vice versa
import { DrawerActions } from 'react-navigation-drawer';
this.props.navigation.dispatch(DrawerActions.openDrawer())
The react-navigation api do not provide more information, but you can consult the NavigationActions api reference for more information.
NavigationActions reference
All NavigationActions return an object that can be sent to the router using navigation.dispatch() method.
Note that if you want to dispatch react-navigation actions you should use the action creators provided in this library.
You need to import NavigationActions in your component and then you can dispatch your action with something like this.props.navigation.dispatch(navigateAction);
import { NavigationActions } from 'react-navigation';
const navigateAction = NavigationActions.navigate({
routeName: 'Profile',
params: {},
action: NavigationActions.navigate({ routeName: 'SubProfileRoute' }),
});
this.props.navigation.dispatch(navigateAction);
also as explained from Ashwin Mothilal, make sure you are passing the navigation prop inside your component. For example you can run a console.warn(props) and immediatly see the result on the emulator.
This is your component:
import { DrawerActions } from 'react-navigation-drawer';
const MenuButton = (props) => {
return (
<View>
<TouchableOpacity onPress={() => {
console.warn(props);
props.navigation.dispatch(DrawerActions.openDrawer());
}}>
<Text>Menu</Text>
</TouchableOpacity>
</View>
)
};
At first, just console the props in Menu button and check if you get openDrawer or closeDrawer or any other method you are looking for then you can call it.

How to pass a prop to all tabs of a createBottomTabNavigator

My application is calling a createBottomTabNavigator from a createSwitchNavigator using the following this.props.navigation.navigate('AppMenu', {UserName: 'First Name'}); The createBottomTabNavigator consists of 2 tabs, one is a Stack Navigator and the second is just a React component. When I navigate to the initialRouteName of the Stack Navigator the prop I passed in is available, but if I select the second tab of the Tab Navigator the prop is not available.
Is there a way I can pass a prop to all tabs of a Bottom Tab Navigator when it is rendered?
Here is a diagram of the applications, and sample code that can be run in Snack.
import React from 'react';
import { Text, View, Button } from 'react-native';
import { createBottomTabNavigator, createStackNavigator, createSwitchNavigator } from 'react-navigation';
class LoginScreen extends React.Component {
_navToMain = () => {
console.log('Login Screen: Passing user: First Name');
this.props.navigation.navigate('AppMenu', {UserName: 'First Name'});
}
render () {
return (
<View style={{flexDirection: 'column', paddingTop:20}}>
<Text>Pass UserName prop to createBottomTabNavigator</Text>
<Button title='Login!' onPress={this._navToMain}/>
</View>
)
}
}
class SyncScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerTitle: 'Sync Screen',
};
};
render () {
return (
<View style={{flexDirection: 'column', paddingTop:20}}>
<Text>Sync Screen Navigation Prop UserName (missing!): {JSON.stringify(this.props.navigation.getParam('UserName'))}</Text>
<Button title='Test Button' onPress={() => {}} />
</View>
);
}
}
class AppMenuScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerTitle: 'Stack Navigator',
};
};
_navToOne = () => {
console.log('Going to Stack One')
this.props.navigation.navigate('StackOne', {UserName: this.props.navigation.getParam('UserName')});
}
render () {
return (
<View style={{flexDirection: 'column'}} >
<Text>App Menu Navigation Prop UserName passed from SwitchNavigator: {JSON.stringify(this.props.navigation.getParam('UserName'))}</Text>
<Button title='Screen one' onPress={this._navToOne} />
</View>
)
}
}
class StackOneScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerTitle: 'Stack One Screen',
};
};
render () {
return (
<View style={{flexDirection: 'row'}} >
<Text>Stack One Screen Navigation Props: {JSON.stringify(this.props.navigation.getParam('UserName'))}</Text>
</View>
)
}
}
const AppStack = createStackNavigator(
{
AppMenu: AppMenuScreen,
StackOne: StackOneScreen,
},
{
initialRouteName: "AppMenu",
navigationOptions: {
headerTintColor: "#a41034",
headerStyle: {
backgroundColor: "#fff"
}
}
}
);
const MainTabs = createBottomTabNavigator(
{
'Apps': { screen: AppStack },
'Sync': { screen: SyncScreen },
},
{
navigationOptions: ({ navigation }) => ({
title: navigation.state,
tabBarIcon: ({ focused, horizontal, tintColor }) => {
const { routeName } = navigation.state;
}
}),
tabBarOptions: {
activeTintColor: 'red',
inactiveTintColor: 'gray',
tabBackgroundColor: 'black',
labelStyle:{
fontSize: 24,
marginBottom:10,
}
},
animationEnabled: true,
swipeEnabled: false,
}
);
const AppNavigator = createSwitchNavigator(
{
Login: LoginScreen,
Main: MainTabs
},
{
initialRouteName: 'Login',
backBehavior: "initialRoute",
}
);
export default class App extends React.Component {
render() {
return (
<AppNavigator />
);
}
}
Package.json
"react": "16.5.0",
"react-native": "0.57.1",
"react-navigation": "^2.0.0"
you can pass props on navigate using
_navToOne = () => {
console.log("Going to Stack One");
this.props.navigation.navigate({
routeName: "StackOne",
params: { UserName: this.props.navigation.state.params.UserName }
});
};
if you want to access props passed using navigate
this.props.navigation.state.params.PROPNAME
// PROPNAME is the prop you passed and want to get
It's just a temporary solution, at least these code can solve your issue
When I navigate to the initialRouteName of the Stack Navigator the prop I passed in is available, but if I select the second tab of the Tab Navigator the prop is not available
because you just sent the param into AppMenu using this.props.navigation.navigate('AppMenu', {UserName: 'First Name'});
UserName is available on both of tab after i change the code of LoginScreen class :
class LoginScreen extends React.Component {
_navToMain = () => {
console.log('Login Screen: Passing user: First Name');
//-------add this-------
this.props.navigation.navigate('Sync', {UserName: 'First Name'});
//----------------------
this.props.navigation.navigate('AppMenu', {UserName: 'First Name'});
}
render () {
return (
<View style={{flexDirection: 'column', paddingTop:20}}>
<Text>Pass UserName prop to createBottomTabNavigator</Text>
<Button title='Login!' onPress={this._navToMain}/>
</View>
)
}
}

How to add header bar when using createBottomTabNavigator?

I'm trying to add a constant Header bar to my screen (all screens, similar to this example) with basic functionality (menu button, and a back button), but I'm having trouble finding a way to do this when using createBottomTabNavigator. I haven't seen anything saying this isn't possible, so if I'm making a design mistake, do let me know.
Here is my minimal foobar example (it runs):
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { createBottomTabNavigator } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
class ScreenA extends React.Component {
constructor(props) {
super(props);
this.state = {
screenName: 'Screen A'
}
}
render() {
return (
<View
style={styles.container}
>
<Text>{this.state.screenName}</Text>
</View>
);
}
};
class ScreenB extends React.Component {
constructor(props) {
super(props);
this.state = {
screenName: 'Screen B'
}
}
render() {
return (
<View
style={styles.container}
>
<Text>{this.state.screenName}</Text>
</View>
);
}
};
const BottomTabNav = createBottomTabNavigator(
{
ScreenA: {
screen: ScreenA,
navigationOptions: {
title: '',
tabBarIcon: ({ focused, tintColor }) => {
return <Ionicons
name={ focused ? 'ios-card' : 'ios-card-outline' }
size={30}
style={{ marginTop: 6 }}
/>;
},
}
},
ScreenB: {
screen: ScreenB,
navigationOptions: {
title: '',
tabBarIcon: ({ focused, tintColor }) => {
return <Ionicons
name={ focused ? 'ios-chatbubbles' : 'ios-chatbubbles-outline' }
size={30}
style={{ marginTop: 6 }}
/>;
},
},
}
},
{
initialRouteName: 'ScreenA',
}
);
export default class App extends React.Component {
render() {
return (
<BottomTabNav />
);
}
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Apologies for not including a Snack link, but I'm having issues with dependencies when trying to build the demo.
You need your screens to be stack navigators which you then can add in your tab navigator. The "defaultNavigationOptions" are your navigationOptions for the header and the navigationOptions in the code snippet corresponds for the BottomTabNavigator options.
You can read more about this here: https://reactnavigation.org/docs/en/navigation-options-resolution.html
const StackA = createStackNavigator({ ScreenA },
{
defaultNavigationOptions: (navigationOptions),
navigationOptions: {
tabBarLabel: 'Screen A',
},
});
const StackB = createStackNavigator({ScreenA},
{
defaultNavigationOptions: (navigationOptions),
navigationOptions: {
tabBarLabel: 'Screen B',
},
});
const tabNavigator = createBottomTabNavigator({StackA, StackB});
only createStackNavigator has its own header so you have to wrap whatever you want in it, according to your question there is two answers to this,
put the createBottomTabNaviagator in a parent createStackNavigator and access the createBottomTabNavigator children routeName and assign it to the parent createStackNavigator header
const BottomTabNav = createBottomTabNavigator({
FirstScreen: ScreenA,
SecondScreen: ScreenB,
});
BottomTabNav.navigationOptions = ({ navigation }) => {
// By default routeName will come from the BottomTabNav,
// but here we can access the children screens
// and give the parent ParentStack that routeName
const { routeName } = navigation.state.routes[navigation.state.index];
// You can do whatever you like here to pick the title based on the route name
const headerTitle = routeName;
return {
headerTitle,
};
};
const ParentStack = createStackNavigator({
Home: BottomTabNav,
AnotherScreen: AnotherScreen,
});
put the child screens in a createStackNavigator so that every child will have its own header
const ScreenA = createStackNavigator({
FirstScreen: ScreenA,
/* other routes here */
});
const ScreenB = createStackNavigator({
SecondScreen: ScreenB,
/* other routes here */
});
const BottomTabNav = createBottomTabNavigator({
FirstScreen: ScreenA,
SecondScreen: ScreenB,
});

How to access the react-navgiation inside of a functional component or class component which doesnt have access to this.props.navigation?

Im doing this inside the react native platform using expo.
I want to display the list of items ( ListItems.js) All_Employees_screen.js . These items are being rendered via a functional component, I want to have a onRowPress() handler to so that upon clicking it i can navigate it to another view, but I dont know how to do it on react-navigation ?
Or since the new functional component can be a class component( this would be better ) how can i access the navigation thing inside it ?
AllProperties.js
import _ from 'lodash';
import React, {
Component
} from 'react';
import {
Button,
ListView,
ScrollView
} from 'react-native';
import ListItem from './ListItem';
import { connect } from 'react-redux';
import { propertiesFetch } from '../../actions';
// import { FormLabel, FormInput } from 'react-native-elements'
class AllPropertiesScreen extends React.Component {
componentWillMount(){
this.props.propertiesFetch();
this.createDataSource(this.props);
}
// we do this componentWillMount & componentWillReceiveProps (nextProps) thing twice, coz once the component is
// loaded it loads all teh values but when user hits another view like Create property, The Property data still exists
// in the global state object,
// we could move all the dc dataSource code into componentWillReceiveProps but its actually gonna benefit us
// if we make sure that we try to build our data source both when the component first loads up
// & when second time after we go back and forth other compoennts.
componentWillReceiveProps(nextProps){
// nextProps are the next set of props that this component will be rendered with
// this.props is still the old set of props
this.createDataSource(nextProps);
}
createDataSource({ properties }){
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.dataSource = ds.cloneWithRows(properties);
}
static navigationOptions = ({ navigation }) => {
const {state, setParams} = navigation;
return {
title: 'All Emplooyee',
headerRight: (
<Button
title='Add'
// onPress={() => setParams({ mode: isInfo ? 'none' : 'info'})}
onPress={() => navigation.navigate('createProperty')
}
/>
),
};
};
goBack(){
console.log('65 - go Back clicked');
}
renderRow(property){
// console.log('67-AllPropertiesScreen =', property);
return <ListItem property={property}
onPress={() => { console.log('65 - go Back clicked') }}
/>;
}
render() {
console.log('72-AllPropertiesScreen this.props', this.props );
return(
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow}
/>
);
}
}
const mapStateToProps = state => {
console.log('83 - AllPropertiesScreen state. properties', state );
const properties = _.map(state.properties, (val, uid ) => {
return { ...val, uid }; // { shift: 'Monday'}
});
return { properties };
};
export default connect(mapStateToProps, {propertiesFetch}) (AllPropertiesScreen);
ListItem.js
import React, { Component } from 'react';
import { Text, TouchableWithoutFeedback, View } from 'react-native';
class ListItem extends Component {
// onRowPress(){
// Actions.employeeEdit({ employee: this.props.employee });
// }
render(){
const { agent_name, cell, address } = this.props.property;
console.log('14- ListItem ', this.props);
return (
<View>
<CardSection>
<Text style={styles.titleStyle}>
name
</Text>
<Text style={styles.titleStyle}>
cell
</Text>
<Text style={styles.titleStyle}>
address
</Text>
</CardSection>
</View>
);
}
}
const styles = {
titleStyle: {
fontSize: 18,
paddingLeft: 15
}
}
export default ListItem;
//
main.js ( this is where I have all the navigation paths hookedup.
class App extends React.Component {
render() {
const MainNavigator = TabNavigator({
// auth: { screen : AuthScreen },
// review: { screen: ReviewScreen },
// signup: { screen : SignupScreen },
followup: { screen: FollowupScreen }, welcome: { screen : WelcomeScreen },
auth: { screen : AuthScreen },
signup: { screen : SignupScreen },
main: {
screen: TabNavigator ({
followup: { screen: FollowupScreen },
map: { screen: MapScreen },
deck: { screen: DeckScreen },
settings : {
screen: StackNavigator ({
settings: { screen: SettingsScreen },
// settings: { screen: SettingsScreen },
UserProfile: { screen: UserProfileScreen },
HelpSupport: { screen: HelpSupportScreen },
Notifications: { screen: NotificationsScreen },
Signout: { screen: SignoutScreen } // not working, Navigation object not accessible inside the component
}) //screen: StackNavigator ({
},
followup : {
screen: StackNavigator ({
followup: { screen: FollowupScreen },
allProperties: { screen: AllPropertiesScreen },
createProperty: { screen: PropertyCreateScreen },
Red: { screen: RedPriorityScreen }, // not working, Navigation object not accessible inside the component
GreyPriority: { screen: GreyPriorityScreen },
}) //screen: StackNavigator ({
},
draw: {
screen: DrawerNavigator ({
drawin: { screen: DrawScreen },
}) //screen: StackNavigator ({
}
}) //screen: TabNavigator
}
}, {
navigationOptions: {
tabBarVisible: false
},
lazy: true
});
return (
<Provider store={store}>
<View style={styles.container}>
<MainNavigator />
</View>
</Provider>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
// alignItems: 'center',
justifyContent: 'center',
},
});
Expo.registerRootComponent(App);
Solution suggested by #Matt but as soon as I put the navigation={this.props.navigation} it complains. undefined is not an object ( evaluating this.props.navigation )
renderRow(property){
return (
<ListItem
property={property}
navigation={this.props.navigation}
onPress={() => {
console.log( '70-on Press inside renderRow ');
}}/>
);
}
If the component is not a screen you have to import the navigation.
Try this:
import React from 'react';
import { Button } 'react-native';
import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
}
}
// withNavigation returns a component that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);
For more info check out
https://reactnavigation.org/docs/connecting-navigation-prop.html
This answer was written for old version of react-navigation V1
I had the same exact problem, and I found out that this.props.navigation is injected only in components that are registered as screen in StackNavigator or TabbNavigator.
but in general you can use navigate from NavigationActions class (source here https://v1.reactnavigation.org/docs/navigation-actions.html#navigate)
note: NavigationActions.navigate receives parameters in different way but works the same way.
so this working for me
import { NavigationActions } from 'react-navigation';
let {navigate} = NavigationActions;
renderRow(property) {
return (
<ListItem
property={property}
onPress={() => { navigate({
routeName: 'OtherRoute'
});
}}/>
);
}
<MyComponent navigation={this.props.navigation}/>
Main problem is here. You didn't define your prop navigation in component. You should add this.
Here's how you can use navigation.navigate inside a functional component:
import { Text, TouchableHighlight } from 'react-native';
const MyComponent = ({ navigation }) => (
<TouchableHighlight
onPress={() => navigation.navigate('OtherRoute')}
underlayColor="blue"/>
<Text>Click to Navigate!</Text>
</TouchableHighlight>
);
export default MyComponent;
When you render MyComponent, you will need to pass navigation as a prop. For example, assume HomeContainer is a screen component:
import React from 'react';
import MyComponent from './MyComponent';
export default HomeContainer extends React.Component {
render() {
return (
<MyComponent navigation={this.props.navigation}/>
);
}
}
Change your renderRow method to the following:
renderRow(property) {
return (
<ListItem
property={property}
onPress={() => { this.props.navigation.navigate('OtherRoute'); }}/>
);
}
where 'OtherRoute' is the name of the route you want to navigate to for that row.