Skip to content

React Navigation doesn't change screen #21337

Closed
@thaprozz

Description

@thaprozz

Environment

[skip envinfo]

{
"name": "my-new-project",
"main": "node_modules/expo/AppEntry.js",
"private": true,
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject",
"test": "node ./node_modules/jest/bin/jest.js --watchAll"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"@expo/samples": "2.1.1",
"axios": "^0.18.0",
"expo": "^30.0.1",
"react": "16.3.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz",
"react-native-htmlview": "^0.13.0",
"react-navigation": "^2.16.0",
"react-redux": "^5.0.7",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0"
},
"devDependencies": {
"jest-expo": "30.0.0"
}
}

I'm using create-react-native-app package, so I'm unable to run the mandatory command, but my environment is described above.

Description

I'm trying to navigate to another screen (Artist) by clicking on an element in a FlatList. This FlatList contains Artist instances, as set in the _renderListItem method. So far I've tried three different approaches (two of them commented out at the moment), but none of them seem to work:

**Method 1: NavigationActions

Method 2: this.props.navigation.navigate

Method 3: Navigator.push**

I managed to pass the params to the other screen, but unfortunately the navigation itself doesn't seem to work; I'm getting the expected values in my logs, but nothing happens and the app stays at LinksScreen (doesn't change screens).

Reproducible Demo

LinksScreen.js

import React, { Component } from 'react';
import { PropTypes } from 'prop-types';
import Artist  from './Artist';
import { createStackNavigator, withNavigation, NavigationActions } from 'react-navigation';
import {
  ScrollView,
  StyleSheet,
  View,
  Text,
  Image,
  FlatList,
  ActivityIndicator,
  TouchableOpacity,
  TouchableHighlight,
} from 'react-native';

export default class LinksScreen extends React.Component {
  constructor(props) {
    super(props);
    this._onAlertTypePressed = this._onAlertTypePressed.bind(this);
  }

  _onAlertTypePressed(typeId: string, typeName: string, imageUrl: string) {
    console.log(typeId)
    console.log(typeName)
    console.log(imageUrl)

// NavigationActions
    // NavigationActions.navigate({
    //                 routeName: 'Artist',
    //                 params: { itemId: typeId, itemName: typeName, itemImageUrl: imageUrl,},
    //               });

// NAVIGATE
     this.props.navigation.navigate('HomeStack',{},
     {
       type: "Navigate",
       routeName: "Artist",
       params: {
         itemId: typeId,
         itemName: typeName,
         itemImageUrl: imageUrl}
             }
           );

// PUSH
  //     this.props.navigator.push({
  //       screen: 'Artist',
  //       title: 'Artist',
  //       passProps: {
  //         itemId: typeId,
  //         itemName: typeName,
  //         itemImageUrl: imageUrl,
  //       },
  //     });
  }

  _renderListItem = ({item}) => (
    <Artist
      itemId={item.id}
      itemName={item.title.rendered}
      itemImageUrl={
        item.better_featured_image
          ? item.better_featured_image.source_url
          : 'http://54.168.73.151/wp-content/uploads/2018/04/brand-logo.jpg'
      }
      onPressItem={this._onAlertTypePressed}
    />
  );

  static navigationOptions = {
    title: 'Links',
  };

  state = {
    data: [],
    isLoading: true,
    isError: false,
  };

  // static propTypes = {
  //   navigation: PropTypes.shape({
  //     navigate: PropTypes.func.isRequired,
  //   }).isRequired,
  // };

  componentWillMount() {
    fetch('http://54.168.73.151/wp-json/wp/v2/pages?parent=38&per_page=100')
      .then(response => response.json())
      .then(responseJson => {
        responseJson.sort(
          (a, b) => (a.title.rendered < b.title.rendered ? -1 : 1)
        );
        this.setState({
          data: responseJson,
          isLoading: false,
          isError: false,
        });
      })
      .catch(error => {
        this.setState({
          isLoading: false,
          isError: true,
        });
        console.error(error);
      });
  }

// Not used anymore.
  renderRow = item => (
    <View style={styles.grid}>
      <Image
        style={styles.thumb}
        source={{
          uri: item.better_featured_image
            ? item.better_featured_image.source_url
            : 'http://54.168.73.151/wp-content/uploads/2018/04/brand-logo.jpg',
        }}
      />
      <Text style={styles.title}>{item.title.rendered}</Text>
    </View>
  );

  getKey = item => String(item.id);

  renderComponent() {
    if (this.state.isLoading) {
      return <ActivityIndicator />;
    } else if (this.state.isError) {
      return <Text>Error loading data</Text>;
    } else {
      return (
        <FlatList
          numColumns={3}
          contentContainerStyle={styles.elementsContainer}
          data={this.state.data}
          renderItem={this._renderListItem}
          keyExtractor={this.getKey}
        />
      );
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <Text
          style={{
            fontSize: 20,
            color: '#FFFFFF',
            marginLeft: 4,
            marginTop: 10,
          }}>
          RESIDENTS
        </Text>
        {this.renderComponent()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#000000',
  },
  elementsContainer: {
    backgroundColor: '#000000',
  },
  grid: {
    marginTop: 15,
    marginBottom: 15,
    marginLeft: 5,
    height: 125,
    width: 115,
    borderBottomWidth: 1,
    borderBottomColor: '#191970',
  },
  title: {
    color: '#FFFFFF',
    textAlign: 'left',
    fontSize: 12,
  },
  thumb: {
    height: 110,
    width: 110,
    resizeMode: 'cover',
  },
});

Artist.js

The console.log in the beginning of the _onPress() method seem to be working (the expected params have the correct values here), but I'm unable to navigate to this screen.

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

class Artist extends React.PureComponent {

  _onPress = () => {
     // console.log(this.props)

     const itemId = this.props.itemId
     const itemName = this.props.itemName
     const itemImageUrl = this.props.itemImageUrl

    console.log(itemId)
    console.log(itemName)
    console.log(itemImageUrl)

// FOR PUSH
  //   this.props.onPressItem(
  //     this.props.itemid,
  //     this.props.itemName,
  //     this.props.itemImageUrl,
  //   );
  // };
}

  static navigationOptions = {
    title: 'Artist',
  };

  render() {
    return (
      <TouchableOpacity
        {...this.props}
        style={styles.grid}
        onPress={this._onPress}>
        <Image
          style={styles.image}
          source={{uri: this.props.itemImageUrl}}
        />
        <Text style={styles.title}>{this.props.itemName}</Text>
      </TouchableOpacity>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#000000',
  },
  grid: {
    marginTop: 15,
    marginBottom: 15,
    marginLeft: 5,
    height: 125,
    width: 115,
    borderBottomWidth: 1,
    borderBottomColor: '#191970',
  },
  title: {
    color: '#FFFFFF',
    textAlign: 'left',
    fontSize: 12,
  },
  image: {
    height: 110,
    width: 110,
    resizeMode: 'cover',
  },
});

export default Artist;

MainTabNavigator.js

Perhaps there is something wrong regarding the routing, so here is how it's done in my case.

import React from 'react';
import { Platform, AppRegistry } from 'react-native';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';

import TabBarIcon from '../components/TabBarIcon';
import HomeScreen from '../screens/HomeScreen';
import LinksScreen from '../screens/LinksScreen';
import SettingsScreen from '../screens/SettingsScreen';
import Artist from '../screens/Artist';

const HomeStack = createStackNavigator({
  Home: {
    screen: HomeScreen,
  },
  Links: {
    screen: LinksScreen,
  },
  Artist: {
    screen: Artist,
  },
});

AppRegistry.registerComponent('ParamsRepo', () => HomeStack);

export default HomeStack;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions