Bpt26
Bpt26

Reputation: 63

Repeated JSON data - React Native

Could anyone explain to me why my data and title are being repeated over and over again and how do I go about to fix this issue?

I also have a yellow error message which I think maybe related, it reads 'Warning: Each child in a list should have a unique "key" prop.'

It is probably something basic but I am new to react and learning a lot from people on here and appreciate the help!

Thank you

Repeated data

import React from "react";
import { StyleSheet, FlatList, Text, View } from "react-native";
import styled from "styled-components";

export default class FetchExample extends React.Component {
  static navigationOptions = {
    header: null
  };

  constructor(props) {
    super(props);
    this.state = { isLoading: true };
  }

  componentDidMount() {
    const localMovieData = require("../assets/test.json");

    this.setState(
      {
        isLoading: false,
        dataSource: localMovieData.movies
      },
      function() {}
    );
  }

  _renderItem = info => {
    return (
      <View>
        <Title style={styles.title}> Contact Information </Title>
        {this.state.dataSource.map((movie, index) => (
          <Text style={styles.text}>
            {movie.name} - {movie.contact}
          </Text>
        ))}
      </View>
    );
  };

  render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.dataSource}
          renderItem={this._renderItem}
          keyExtractor={({ id }, index) => id}
        />
      </View>
    );
  }
}
const Title = styled.Text`
  font-size= 16px;
  color: #b8bece;
  font-weight: 500;
  `;

const styles = StyleSheet.create({
  container: {
    paddingVertical: 50,

    backgroundColor: "#f0f3f5"
  },
  text: {
    fontSize: 15,
    color: "#008000",
    padding: 10
  },
  image: {
    width: 45,
    height: 45,
    borderRadius: 20,
    marginLeft: 20
  },
  title: {
    fontSize: 16,
    color: "black"
  }
});

JSON Data

{
  "title": "The Basics - Networking",
  "description": "Your app fetched this from a remote endpoint!",
  "movies": [
    { "id": "1", "name": "Tim ", "contact": "[email protected]" },
    { "id": "2", "name": "Bradley", "contact": "[email protected]" },
    { "id": "3", "name": "James", "contact": "outlook.com" },
    { "id": "4", "name": "Elle", "contact": "hotmail" },
    { "id": "5", "name": "Bob", "contact": "yahoo" }
  ]
}

Upvotes: 1

Views: 216

Answers (2)

Dor Lugasi-Gal
Dor Lugasi-Gal

Reputation: 1572

The problem is with your "renderItem" method

when a FlatList component receives data, it automatically separates it to objects and send each one to the"renderItem" method

so what you need to do is : in the render function take the item property of each item and send it into the _renderItem

remove the mapping inside each renderItem and access the new item like so:

_renderItem = item => {
    return (
      <View>
        <Text style={styles.title}> Contact Information </Text>         
          <Text>
            {item.name} - {item.contact}
          </Text>
      </View>
    );
  };

  render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.dataSource}
          renderItem={(item)=>this._renderItem(item.item)}
          keyExtractor={(item, index) => {return item.id;}}  
      />
      </View>
    );
  }

as for the key warning:

You need to return the Key like this

keyExtractor={(item, index) => {
     return item.id;
    }}

you can see a working code here

Upvotes: 4

Raj Kumar N
Raj Kumar N

Reputation: 793

You don't need to loop over the datasource inside _renderItem, because FlatList will call it's renderItem function for each array item.

So change your _renderItem function as below

_renderItem = el => {
  const movie = el.item;
  return (
    <View>
      <Title style={styles.title}> Contact Information </Title>  
      <Text style={styles.text}>
        {movie.name} - {movie.contact}
      </Text>
    </View>
  );
};

Upvotes: 1

Related Questions