Nabin Dhakal
Nabin Dhakal

Reputation: 2182

Flatlist displaying same items multiple times

I am using flatlist to render data from api, the data are rendered and also displayed. But the problem is the items are displayed multiple times. I got 5 items from the api but those 5 items are repeating.

enter image description here

I have implemented as follows:

export default class FlatSpeakers extends Component {
constructor(props) {
    super(props);
    this.state = { isLoading: true, data: [] }
}
componentDidMount() {
    axios.get('https://rallycoding.herokuapp.com/api/music_albums')
       .then(res => {
            this.setState({
                isLoading: false,
                data: res.data,
            })
        })
}
renderItem() {
    return (
        this.state.data.map(item =>
          <SpeakersDetails key={item.title} speakerD={item} />
        )
      )
}

render() {
    if (this.state.isLoading) {
        return (
           <View style={{ flex: 1, padding: 20 }}>
                <ActivityIndicator />
            </View>
        )
    }

    return (
        <View style={styles.container}>
            <FlatList
                data={this.state.data}
                renderItem={this.renderItem.bind(this)}
                keyExtractor={item => item.id}
            />
        </View>
    );
}
}

I have implemented the SpeakersDetails component as follows:

const SpeakersDetails = ({ speakerD }) => {

const { title, artist, thumbnail_image, image, url } = speakerD;
const {
    thumbnailStyle,
    headerContentStyle,
    thumbnailContainerStyle,
    headerTextStyle,
    imageStyle
} = styles;

return (
    <Card>
        <CardSection>
            <View style={thumbnailContainerStyle}>
                <Image
                    style={thumbnailStyle}
                    source={{ uri: image }}
                />
            </View>
            <View style={headerContentStyle}>
                <Text style={headerTextStyle}>{title}</Text>
                <Text>{artist}</Text>
            </View>
        </CardSection>
    </Card>
);
 };

Upvotes: 4

Views: 5876

Answers (3)

Lasitha Lakmal
Lasitha Lakmal

Reputation: 880

Try this way

const adList = useCallback((ad: any) => (
   <View>
      //Your item design
   </View>
), []);

Then In flat list use it like this

<FlatList keyExtractor={(contact, index) => String(index)}  data={ad_set} renderItem={adList} />

For more refer this link, and look at the bottom

https://reactnative.dev/docs/optimizing-flatlist-configuration

Upvotes: 0

mmmatey
mmmatey

Reputation: 684

You should change you flat list callback for rendering FlatList item, to passing item into renderItem function. Now you are iterating over your state as many times as you got items from API call. Meaning 5 items per 5 times repeating.

Solution to your problem is to make call and make renderItem function like this below, you should pass item object into renderItem function:

<FlatList
    data={this.state.data}
    renderItem={({item}) => this.renderItem.bind(this, item)}
    keyExtractor={item => item.id} />

Your renderItem function call should accept item object as argument and render UI from passed object:

renderItem(item) {
    return (
        <SpeakersDetails key={item.title} speakerD={item} />
    )
}

Upvotes: 1

bug
bug

Reputation: 4130

FlatList iterates over data and call renderItem for each item in it, you are rendering the full list at every call, that's why you get items duplicated.

renderItem receives the current item as parameter, try change your function like this:

renderItem({item}) {
    return (
          <SpeakersDetails key={item.title} speakerD={item} />
      )
}

Check the renderItem documentation for further details, including additional parameters this function receives.

Upvotes: 1

Related Questions