Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlatList onViewableItemsChanged does not trigger when getItemLayout is used #13454

Closed
gp3gp3gp3 opened this issue Apr 11, 2017 · 0 comments
Closed
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@gp3gp3gp3
Copy link

gp3gp3gp3 commented Apr 11, 2017

Description

I'm using the FlatList component to render a collection of images/video components on a phone. When my data gets fetched and passed into the component from redux, all the images make network requests for the uri's I give the components. Because of this I'm getting some frame rate drops and the list becomes jarring.

So I've started using the onViewableItemsChanged prop to keep track of the currently viewed items and only render those components when they enter the view (This behavior is working on its own with android but not iOS). Although has helped to not clog up whatever is making the feed stutter, it still has some frame drops. After implementing PureComponent I passed the FlatList the getItemLayout prop and the onViewableItemsChange callback stops firing off entirely.

Sorry no snack.expo project, flat list doesn't seem to be supported.

Reproduction Steps and Sample Code

import React, { PureComponent } from 'react'
import {
  View,
  Text,
  FlatList,
  Dimensions
} from 'react-native'
import chunk from 'lodash/chunk'

import Tile from '../Tile'

class Browse extends PureComponent {
  constructor () {
    super()
    this.state = {
      viewedItems: []
    }
    this.onItemsChanges = this.onItemsChanges.bind(this)
  }

  onItemsChanges ({ viewableItems }) {
    console.log('I am not being fired off')
  }

  renderGenres ({ item }) {
    return (
      <View style={styles.genresStyle}>
        {item.map(genre => (
          <Tile
            picture={genre.picture}
            key={genre.id}
            title={genre.name}
            itemId={genre.id}
            whenPressed={this.whenPressed.bind(this, genre)}
            {...this.state}
          />
        ))}
      </View>
    )
  }

  whenPressed (genre) {
    this.props.onGenrePress({ genre })
  }
  render () {
    const {
      containerStyle,
      titleStyle
    } = styles
    return (
      <View style={containerStyle}>
        <Text style={titleStyle}>Genres</Text>
        <FlatList
          style={{height: screenHeight}}
          data={chunk(this.props.genres, 2)}
          renderItem={this.renderGenres.bind(this)}
          keyExtractor={chunk => chunk[0].id}
          onViewableItemsChanged={this.onItemsChanges}
          getItemLayout={(item, index) => (
            {length: 172, offset: 172 * index, index}
          )}
        />
      </View>
    )
  }
}

const screenHeight = Dimensions.get('window').height

const styles = {
  containerStyle: {
    flex: 1,
    paddingBottom: 50,
    backgroundColor: '#7C3BFF'
  },
  titleStyle: {
    fontSize: 24,
    fontWeight: 'bold',
    textAlign: 'center',
    marginBottom: 10,
    marginTop: 10,
    color: 'white'
  },
  genresStyle: {
    justifyContent: 'center',
    alignItems: 'center',
    flexWrap: 'wrap',
    flexDirection: 'row'
  }
}

export default Browse

If the getItemLayout prop is removed the console log is fired off.

Solution

Any advice on optimization of the flat list to remove frame rate drops and deal with large lists would be fantastic. Just trying to get performance up to speed with large lists of images/ .mp4s using videos.

Additional Information

  • React Native version: 0.43.2
  • Platform: both
  • Development Operating System: MacOS
  • Dev tools: Xcode: 8.3.1. Android Studio 2.2.3. Same behavior on iPhones 5, 6 and 7.

Edit

It seems the callback is actually firing off now. Not sure what I changed from before but any additional advice on optimizing performance so that the child components are not blocking the UI would be great. Feel free to close this though as the title of the issue is not accurate anymore.

@facebook facebook locked as resolved and limited conversation to collaborators May 24, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

2 participants