javascriptreact-nativereact-native-flatlistreact-native-listview

VirtualizedList: missing keys for items - React Native


On my componentDidMount() I do a Query where I receive some documents from a MongoDb database which I want to show in a FlatList. When I have received the results from the Query I map them to my state.list with the function mapToList() The list.id I use here is an inserted document _id generated by MongoDb itself. Just to have a id to work with here. Then I add key={item.id} to my renderItem({item}) method, but I still get the error that I have to add keys to my VirtualizedList or use a KeyExtractor.

I'm trying to delete an item from the FlatList with the use of Swipeout but first I have to get this id thing to work.

export default class MyFlatList extends React.Component{
 state={   
 loading: false,
 list: [{
   name: '',
   subtitle: '',
   rightSubtitle: '',
   rightTitle: '',
   id: undefined
 }]
};

mapToList();

mapToList(result)
{ 
  const list = [];
  for(var i = 0; i<result.length; i++)
  {
      list[i] =  {name: result[i].name,
      subtitle : result[i].projectname,
      rightTitle : result[i].work,
      rightSubtitle : result[i].date,
      id: result[i]._id
    };
  }
  this.setState({list});
}

render()

  render(){
  return(
    <View>
    <FlatList
      data={this.state.list}
      renderItem={this.renderItem}
      />
      <ActivityIndicator animating={this.state.loading} color="black" size="large"/>
    </View>
        )
  }

renderItem({item})

renderItem = ({item}) => (
  <Swipeout right={swipeoutBtns}>
  <ListItem
    title={item.name}
    key={item.id}
    titleStyle={styles.titleText}
    subtitleStyle={styles.subtitleText}
    rightTitleStyle={styles.rightSubtitleText}
    rightSubtitleStyle={styles.rightSubtitleText}
    rightIcon={
      <Icon name="keyboard-arrow-right"
          size={17}
          color="black"
        />}
    subtitle={item.subtitle}
    rightTitle={item.rightTitle}
    rightSubtitle={item.rightSubtitle}
    leftAvatar={{rounded:false, title:'PS'}}
  />
  </Swipeout>
)

Solution

  • You need keyExtractor parameter. As default it will check if the item has a key property which you don't that why you are getting this warning.

    Used to extract a unique key for a given item at the specified index. Key is used for caching and as the react key to track item re-ordering. The default extractor checks item.key, then falls back to using the index, like React does.

    Do this:

     _keyExtractor = (item, index) => item.id.toString();
    
    <FlatList
       data={this.state.list}
       renderItem={this.renderItem}
       keyExtractor={this._keyExtractor}
     />