1

I did find this question in a few other places, but I'm still unable to resolve the issue with any of the help given. I got most of the code so far from this article -

https://medium.com/@austinhale/building-a-mobile-app-in-10-days-with-react-native-c2a7a524c6b4

Some of the APIs were outdated, but most of them I was able to replace with the new version - One of the APIs i changed that might be notable in regards to this question is stackNavigator -> createStackNavigator

My code is as follows:

Apps.js

import React, { Component } from 'react';
import {
    FlatList,
    StatusBar,
    StyleSheet,
    Text,
    View
} from 'react-native';

import AppItem from './AppItem';

export default class Apps extends Component {
    constructor(props) {
        super(props);
        this.state = {
            apps: [
                {
                    id: 1,
                    title: 'Good Business',
                    description: 'Make millions investing in mindtree minds',
                    thumbnail: 'https://img12.androidappsapk.co/300/f/5/1/com.nse.bse.sharemarketapp.png'
                },
                {
                    id: 2,
                    title: 'Troll WhatsApp SOS ONLY',
                    description: 'Have a laugh by reading all the comments in the group chat made by your coworkers',
                    thumbnail: 'http://icons.iconarchive.com/icons/dtafalonso/android-l/256/WhatsApp-icon.png'
                }

            ]
        }
    }

    _renderItem = ({ item }) => (
        <AppItem
            id={item.id}
            title={item.title}
            description={item.description}
            thumbnail={item.thumbnail}
        />
    );

    _keyExtractor = (item, index) => item.id.toString();

    render() {
        return (
            <View style={styles.container}>
                <StatusBar
                    barStyle="light-content"
                />
                <FlatList
                    data={this.state.apps}
                    keyExtractor={this._keyExtractor}
                    renderItem={this._renderItem}
                />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    }
});

router.js

import React, { Component } from 'react';
import { Dimensions, Platform } from 'react-native';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';
import { Icon } from 'react-native-elements';

import Apps from './screens/Apps';
import Gallery from './screens/Gallery';
import Garage from './screens/Garage';
import News from './screens/News';
import Support from './screens/Support';
import ViewApp from './screens/ViewApp';

let screen = Dimensions.get('window');

export const Tabs = createBottomTabNavigator({
    'Apps': {
        screen: Apps,
        navigationOptions: {
            tabBarLabel: 'Apps',
            tabBarIcon: ({ tintColor }) => <Icon raised name="ios-apps-outline" type="ionicon" size={28} color={tintColor} />
        },
    },
    'News': {
        screen: News,
        navigationOptions: {
            tabBarLabel: 'News',
            tabBarIcon: ({ tintColor }) => <Icon raised name="newspaper-o" type="font-awesome" size={28} color={tintColor} />
        },
    },
    'Garage': {
        screen: Garage,
        navigationOptions: {
            tabBarLabel: 'Garage',
            tabBarIcon: ({ tintColor }) => <Icon raised name="garage" type="material-community" size={28} color={tintColor} />
        },
    },
    'Gallery': {
        screen: Gallery,
        navigationOptions: {
            tabBarLabel: 'Gallery',
            tabBarIcon: ({ tintColor }) => <Icon raised name="picture" type="simple-line-icon" size={28} color={tintColor} />
        },
    },
    'Support': {
        screen: Support,
        navigationOptions: {
            tabBarLabel: 'Support',
            tabBarIcon: ({ tintColor }) => <Icon raised name="ios-person-outline" type="ionicon" size={28} color={tintColor} />
        },
    },
});

export const AppsStack = createStackNavigator({
    Apps: {
        screen: Apps,
        navigationOptions: ({ navigation }) => ({
            header: null,
        }),
    },
    ViewApp: {
        screen: ViewApp,
        navigationOptions: ({ navigation }) => ({
            header: null,
            tabBarVisible: false,
            gesturesEnabled: false
        }),
    },
});

export const createRootNavigator = () => {
    return createStackNavigator(
        {
            AppsStack: {
                screen: AppsStack,
                navigationOptions: {
                    gesturesEnabled: false
                }
            },
            Tabs: {
                screen: Tabs,
                navigationOptions: {
                    gesturesEnabled: false
                }
            }
        },
        {
            headerMode: "none",
            mode: "modal"
        }
    );
};

AppItem.js

import React, { Component } from 'react';
import {
    StyleSheet,
    TouchableOpacity,
    Text,
    Image,
    View
} from 'react-native';

import { Icon } from 'react-native-elements';
import { ViewApp } from './ViewApp';

export default class AppItem extends Component {

    _onViewApp = () => {
        let id = this.props.id;
        this.props.navigation.navigate('ViewApp', { id: id })
    }

    render() {

        return (
            <TouchableOpacity onPress={this._onViewApp}>
                <View style={styles.rowContainer}>
                    <Image source={{ uri: this.props.thumbnail }}
                        style={styles.thumbnail}
                        resizeMode="contain" />
                    <View style={styles.rowText}>
                        <Text style={styles.title} numberOfLines={2} ellipsizeMode={'tail'}>
                            {this.props.title}
                        </Text>
                        <Text style={styles.description} numberOfLines={2} ellipsizeMode={'tail'}>
                            {this.props.description}
                        </Text>
                    </View>
                </View>
            </TouchableOpacity>
        );
    }
}

const styles = StyleSheet.create({
    rowContainer: {
        flexDirection: 'row',
        backgroundColor: '#FFF',
        height: 100,
        padding: 10,
        marginRight: 10,
        marginLeft: 10,
        marginTop: 15,
        borderRadius: 4,
        shadowOffset: { width: 1, height: 1, },
        shadowColor: '#CCC',
        shadowOpacity: 1.0,
        shadowRadius: 1
    },
    title: {
        paddingLeft: 10,
        paddingTop: 5,
        fontSize: 16,
        fontWeight: 'bold',
        color: '#777'
    },
    description: {
        paddingLeft: 10,
        marginTop: 5,
        fontSize: 14,
        color: '#777'
    },
    thumbnail: {
        flex: 1,
        height: undefined,
        width: undefined
    },
    rowText: {
        flex: 4,
        flexDirection: 'column'
    }
});
Cristiano Santos
  • 2,157
  • 2
  • 35
  • 53
jacob blankenship
  • 145
  • 1
  • 3
  • 16
  • According to [the documentation](https://reactnavigation.org/docs/en/navigation-prop.html), `this.props.navigation` will only be automatically added to *screens*, not all components. So whatever it is that makes a component a *screen* (I don't use react-navigation), you're not doing it for `AppItem`. – T.J. Crowder Jul 09 '18 at 09:59
  • You've tagged [tag:react-router], but you're not using it, are you? You're using [tag:react-navigation], right? – T.J. Crowder Jul 09 '18 at 10:00

2 Answers2

0

You can change your onPress functionality in AppItem.js like below. Use arrow function inside your onPress onPress={() => this._onViewApp()}. Because Arrow function does not create the context "this". It refers to the context of the component that it was wrapped in. For lexical this refer this Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?

import { Icon } from 'react-native-elements';
import { ViewApp } from './ViewApp';

export default class AppItem extends Component {

    _onViewApp(){
        let id = this.props.id;
        this.props.navigation.navigate('ViewApp', { id: id })
    }

    render() {

        return (
            <TouchableOpacity onPress={() => this._onViewApp()}>
                <View style={styles.rowContainer}>
                    <Image source={{ uri: this.props.thumbnail }}
                        style={styles.thumbnail}
                        resizeMode="contain" />
                    <View style={styles.rowText}>
                        <Text style={styles.title} numberOfLines={2} ellipsizeMode={'tail'}>
                            {this.props.title}
                        </Text>
                        <Text style={styles.description} numberOfLines={2} ellipsizeMode={'tail'}>
                            {this.props.description}
                        </Text>
                    </View>
                </View>
            </TouchableOpacity>
        );
    }
}
Jeeva
  • 1,550
  • 12
  • 15
0

I wanted to follow up for everyone who's having the same issue. I just included withNavigation from 'react-native-navigation'; and exported at the end of the component like so export default withNavigation(AppItem);.

jacob blankenship
  • 145
  • 1
  • 3
  • 16