Skip to content

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined #21300

Closed
@thaprozz

Description

@thaprozz

I'm dealing with a JSON response in React Native that's coming from the WordPress REST API, containing pages with each an (profile page) ID, title and featured image.

Using a FlatList, I have created a screen with featured images and titles for each (Artist) page. I want to add the functionality to navigate to each individual page by clicking on an item in the FlatList, and passing the title, featured image and (later) the content of the regarding page to the next screen to display this information (probably based on the ID).

LinksScreen.js

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

export default class LinksScreen extends React.Component {

constructor(props) {
        super(props);
        this._onAlertTypePressed = this._onAlertTypePressed.bind(this);
        this.state = {
            data: [],
        }
    }

  _onAlertTypePressed(typeId: any, typeName: any, imageUrl: any){

        this.props.navigator.push({
            screen: 'Artist',
            title: 'Artist',
            passProps: {
                alertId: typeId,
                alertName: typeName,
                alertImage: imageUrl,
            }
        });
    }

    _renderListItem = ({ item }) => (
        <Artist
            itemName={ item.title.rendered }
            itemId={ item.id }
            itemImageUrl={ item.better_featured_image.source_url}
            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);
      });
  }

  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={({ item }) => 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

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

export class Artist extends React.PureComponent {
  constructor(props) {
    super(props);
  }

  _onPress = () => {
    this.props.onPressItem(
      String(this.props.itemId),
      String(this.props.itemName),
      String(this.props.itemImageUrl)
    );
  };

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

  render() {
    // const artist = this.props.navigation.state.params.artist;
    return (
      <TouchableOpacity
        {...this.props}
        style={styles.container}
        onPress={this._onPress}>
        <Image
          style={styles.image}
          source={{
            uri: this.props.itemImageUrl
              ? this.props.itemImageUrl
              : 'http://54.168.73.151/wp-content/uploads/2018/04/brand-logo.jpg',
          }}
        />
        <Text style={styles.title}>{this.props.itemName}</Text>
      </TouchableOpacity>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#000000',
  },
  title: {
    color: '#FFFFFF',
    textAlign: 'left',
    fontSize: 12,
  },
  image: {
    height: 350,
    width: 350,
    resizeMode: 'cover',
  },
});

I'm getting an error at the moment - saying that the a string is expected, but an undefined type was found. I used to do it in a different way, but I'm unable to pass the ID (which should be the identifier to pass the data to the next screen) to open a specific generated screen for each artist.

Error:

image

Here is the edible code:

https://snack.expo.io/@jvdl2711/artist-navigation

It used to be like this:

https://snack.expo.io/@jvdl2711/artists (working grid version, but no navigation functionality. I'm sure it gives a good indication of how it's supposed to work.)

Notes

Please, don't mind the titles at the moment. I still have a small unsolved issue regarding unicodes, but I think this won't matter when passing the titles to another screen.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Ran CommandsOne of our bots successfully processed a command.Resolution: LockedThis issue was locked by the bot.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions