Problems wanting to bring a parameter with getParam in React Native

0

I have a question, I'm doing an app with React Native and Redux, similar to what Twitter is. In the Home a timeline of tweets is loaded of which when I play in one of them, I have to show that particular tweet. The problem is that when I click or take a particular tweet I get the following error:

The sequence is as follows (below I show you images): From the home.js file I pass to Timeline.js the data of the tweets, in this file by means of a TouchableOpacity, to select a special tweet, it is executed an action by passing the tweet data to navReducer.js. This file filters the route and passes the data to TweetScreen.js which in turn through getParam I want to pass it to the Tweet.js component. The error seems to be in TweetScreen when I call navigation.state.getParam.

//AppNavigator.js

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createStackNavigator, createMaterialTopTabNavigator } from 'react-navigation';
import {
  reduxifyNavigator,
  createReactNavigationReduxMiddleware,
} from 'react-navigation-redux-helpers';
import { Ionicons } from '@expo/vector-icons';
import Routes from '../config/routes';
import HomeScreen from '../screens/HomeScreen';
import SearchScreen from '../screens/SearchScreen';
import SettingsScreen from '../screens/SettingsScreen';
import Home from './home/home';
import TweetScreen from '../screens/TweetScreen';

const middleware = createReactNavigationReduxMiddleware(
  'root',
  state => state.nav
);

const RootNavigator = createMaterialTopTabNavigator({
  Home: HomeScreen,
  Search: SearchScreen,
  Settings: SettingsScreen, 
}, {
    navigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ horizontal, tintColor }) => {
        const { routeName } = navigation.state;
        let iconName;
        switch(routeName) {
          case 'Home':
            iconName = 'md-home';
            break;
          case 'Search':
            iconName = 'md-search';
            break;
          case 'Settings':
            iconName = 'md-settings';
            break;
        }

        return <Ionicons name={iconName} size={30} color={tintColor} />;
      },
    }),
    tabBarOptions: {
      activeTintColor: '#000',
      showIcon: true,
      showLabel: false,
      inactiveTintColor: 'gray',
      style: {
        backgroundColor: '#fff',
        padding:20,
      },
      iconStyle: {
        justifyContent: 'center',
        alignItems: 'center',
      },
      indicatorStyle: {
        backgroundColor: '#000',
      },
    }
});

const TweetStack = createStackNavigator({
  Home: {
    screen: RootNavigator,
    navigationOptions: ({ navigation }) => ({
      title: 'Gwitter',
    }),
  },
  Tweet: TweetScreen
});

const AppWithNavigationState = reduxifyNavigator(TweetStack, 'root');

const mapStateToProps = state => ({
  state: state.nav,
});

const AppNavigator = connect(mapStateToProps)(AppWithNavigationState);


export { TweetStack, AppNavigator, middleware };

//home.js

'use strict';

import React, { Component } from 'react';
import {
    StyleSheet,
    FlatList,
    View,
    ActivityIndicator
} from 'react-native';
import {bindActionCreators} from 'redux';
import { connect } from 'react-redux';
import * as Actions from '../../actions/homeActions'; //Import your actions
import Timeline from './Timeline';



class Home extends Component {

    constructor(props) {
        super(props);
        this.state = {
        
        };
        
        this.renderItem = this.renderItem.bind(this);
    }
    
    componentDidMount() {
        this.props.getTweetsTimeline(0); //call our action
    }

    render() {
        if (this.props.loading) {
            return (
                <View style={styles.activityIndicatorContainer}>
                    <ActivityIndicator animating={true}/>
                </View>
            );
        } else {
            return (
                <View style={{flex:1, backgroundColor: '#F5F5F5', paddingTop:20}}>
                    <FlatList
                        ref='listRef'
                        data={this.props.data}
                        onEndReached={this.handleEnd}
                        onEndReachedThreshold={0}
                        renderItem={this.renderItem}
                        keyExtractor={(item, index) => index.toString()}/>
                </View>
            );
        }
    }

    handleEnd() {
        this.props.getTweetsTimeline(this.props.page);
    }

    renderItem({item}) {
        return (
            <Timeline 
                tweet={item}
                navigation={this.props.navigation} 
            />
        )
    }
};

// The function takes data from the app current state,
// and insert/links it into the props of our component.
// This function makes Redux know that this component needs to be passed a piece of the state
function mapStateToProps(state, props) {
    return {
        loading: state.homeReducer.loading,
        data: state.homeReducer.data
    }
}

// Doing this merges our actions into the component’s props,
// while wrapping them in dispatch() so that they immediately dispatch an Action.
// Just by doing this, we will have access to the actions defined in out actions file (action/home.js)
function mapDispatchToProps(dispatch) {
    return bindActionCreators(Actions, dispatch);
}

//Connect everything
export default connect(mapStateToProps, mapDispatchToProps)(Home);

const styles = StyleSheet.create({
    activityIndicatorContainer:{
        backgroundColor: "#fff",
        alignItems: 'center',
        justifyContent: 'center',
        flex: 1,
    },
});

//Timeline.js

'use strict';

import React, { Component } from 'react';
import {
    StyleSheet,
    FlatList,
    View,
    Text,
    ActivityIndicator,
    Image,
    TouchableOpacity
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import {StackNavigator} from 'react-navigation';

const Timeline = props => {
	
	let tweetMedia;

	//Some cases tweets doesnt have pictures
	if(props.tweet.entities.media) {
		//If there is a picture save it in tweetMedia, to render it later on
		tweetMedia = props.tweet.entities.media.map(picture => {
        	return (
            	<Image
                	source={{uri: picture.media_url}}
                	key={picture.id}
                	style={styles.tweetPicture}
            	/>
        	)
    	})
	}

    return (
    	<View style={styles.row}>
            <View style={styles.userPictureContainer}>
                <Image 
                    source={{uri: props.tweet.user.profile_image_url}}
                    style={styles.userProfileImage}
                />
            </View>
	        <View style={styles.tweetContainer}>
	            <TouchableOpacity
                    onPress={() => props.navigation.dispatch({type: 'Tweet', payload: props.tweet})}
                >
                <View>
	                <Text style={styles.tweetUsername}>
	                    {props.tweet.user.name} <Text style={styles.tweetUsernameInfo}>@{props.tweet.user.screen_name} </Text>
	                </Text>
	        	</View>
	            <View>
	                <Text>
	        	        {props.tweet.text}
	                </Text>
	            </View>
                </TouchableOpacity>
	            <View style={styles.tweetMedia}>
	                {tweetMedia}                                            
	            </View>
	            <View style={styles.socialIconsContainer}>
	            	<View style={styles.socialIcon}>
	            		<Ionicons name='md-heart' size={25} color='#000' />
	            		<Text style={styles.socialIconCounter}>{props.tweet.favorite_count}</Text>
	            	</View>
	            	<View style={styles.socialIcon}>
	            		<Ionicons name='md-refresh'size={25} color='#000' />
	            		<Text style={styles.socialIconCounter}>{props.tweet.retweet_count}</Text>
	            	</View>
	            	<View style={styles.socialIcon}>
	            		<Ionicons name='md-send' size={25} color='#000' />
	            		<Text></Text>
	            	</View>
	            </View>
	        </View>
        </View>
    )
}

export default Timeline;
    
asked by Matias 14.11.2018 в 02:39
source

0 answers