React-native: [Flatlist] initialScrollIndex doesn't work at all

Created on 11 Jul 2017  路  15Comments  路  Source: facebook/react-native

Is this a bug report?

Yes

Have you read the Bugs section of the Contributing to React Native Guide?

Yes

Environment

react-native: 0.45.1

Steps to Reproduce

(Write your steps here:)

Made a horizontal flatlist with initialScrollIndex. It should go to the index and stay there.

<FlatList
        data={list}
        disableVisualisation="false"
        keyExtractor={this.keyExtractor}
        renderItem={this.renderItems}
        horizontal={true}
        scrollEventThrottle={2000}
        pagingEnabled={true}
        initialScrollIndex={8}
        showsHorizontalScrollIndicator={false}
        onScroll={this.scroll}
        getItemLayout={this.layout}
        initialNumToRender={3}
      />

Actual Behavior

It goes to the right index and after about a half second it goes back to the first item in the list.

No idea how to implement it, because method scrollToIndex didn't work too.

Stale

Most helpful comment

@hramos
@jstheoriginal I resolved my problem - my getItemLayout was wrong, but now I have similar issue. It goes to the good index, then I't blank for about 0.5s and then it's rerendering the item on the good index. My component doesn't rerender. OnScroll and scrollEventThrottle works and they have no affect on my issue. InitialNumToRender didn't helped too even with higher number than initialScrollIndex.

const widthScreen = Dimensions.get("window").width;
class HorizontalArticlesListView extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      list: [],
    };
  }
  componentWillMount() {
    let { data, id, hotspotTop, hotspotBottom } = this.props.navigation.state.params;
    this.setState({ list: [hotspotTop, hotspotBottom, ...data] });
  }
  renderItems = ({ item }) => {
    return (
      <ArticleTypeHOC id={item.type + item.id} article={item} navigation={this.props.navigation} />
    );
  };

  keyExtractor = (article, index) => article.url;

  layout = (data, index) => ({ length: widthScreen, offset: widthScreen * index, index });

  render(): JSX.JSXElement {
    return (
      <FlatList
        data={this.state.list}
        disableVisualisation={false}
        keyExtractor={this.keyExtractor}
        renderItem={this.renderItems}
        horizontal={true}
        scrollEventThrottle={250}
        pagingEnabled={true}
        initialScrollIndex={9}
        showsHorizontalScrollIndicator={false}
        onScroll={this.scroll}
        getItemLayout={this.layout}
        initialNumToRender={1}
      />
    );
  }
}
export default HorizontalArticlesListView;

All 15 comments

Can you reproduce this using Snack?

It could be because your initalNumToRender is lower than the initialScrollIndex.

@hramos probably not :(. It's a pretty big app and I would need to put there the whole app. I just though somebody had this problem before :(

@jstheoriginal didn't work :(

Did you check whether something in your onScroll or scrollEventThrottle may be reacting to the initial scroll the app is doing that causes it to go back to the start? Does it do it if you change the Flatlist to vertical?

@hramos
@jstheoriginal I resolved my problem - my getItemLayout was wrong, but now I have similar issue. It goes to the good index, then I't blank for about 0.5s and then it's rerendering the item on the good index. My component doesn't rerender. OnScroll and scrollEventThrottle works and they have no affect on my issue. InitialNumToRender didn't helped too even with higher number than initialScrollIndex.

const widthScreen = Dimensions.get("window").width;
class HorizontalArticlesListView extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      list: [],
    };
  }
  componentWillMount() {
    let { data, id, hotspotTop, hotspotBottom } = this.props.navigation.state.params;
    this.setState({ list: [hotspotTop, hotspotBottom, ...data] });
  }
  renderItems = ({ item }) => {
    return (
      <ArticleTypeHOC id={item.type + item.id} article={item} navigation={this.props.navigation} />
    );
  };

  keyExtractor = (article, index) => article.url;

  layout = (data, index) => ({ length: widthScreen, offset: widthScreen * index, index });

  render(): JSX.JSXElement {
    return (
      <FlatList
        data={this.state.list}
        disableVisualisation={false}
        keyExtractor={this.keyExtractor}
        renderItem={this.renderItems}
        horizontal={true}
        scrollEventThrottle={250}
        pagingEnabled={true}
        initialScrollIndex={9}
        showsHorizontalScrollIndicator={false}
        onScroll={this.scroll}
        getItemLayout={this.layout}
        initialNumToRender={1}
      />
    );
  }
}
export default HorizontalArticlesListView;

Use recordInteraction() if you wanna force FlatList to re-render extraData enabled

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.

@DevSzurmanski - I am also encountering the same issue. What was the problem with your getItemLayout function?

This is my current code:

      <ScreenWrapper>
          <FlatList
            style={{
              width: WIDTH,
              marginLeft: -20,
            }}
            data={messages}
            initialScrollIndex={messages.length - 1}
            renderItem={this.renderItem}
            keyExtractor={item => item.id}
            getItemLayout={(data, index) => (
              { length: HEIGHT, offset: HEIGHT * index, index }
            )}
          />
      </ScreenWrapper>

I had same issue. Here's my working workaround:
contentOffset = {{x: ITEM_WIDTH * this.props.startAtIndex, y: 0}}

@Ahad-Wasim what if the HEIGHT is different for each item? Want to know how to calculate the content height. Thanks.

from VirtualizedList.js 0.55.2

invariant(
      index >= 0 && index < getItemCount(data),
      `scrollToIndex out of range: ${index} vs ${getItemCount(data) - 1}`,
    );

how are we supposed to have initialScrollIndex to be the last index ?

@chinalwb Precompute the offset and store it in your dataset, then just return that specific item's data in the getItemLayout method. Messy.

@pcguru Could you give me some pointer about how to 'Precompute the offset' if each item has a different height? (my app is similar to the IM app, the item's height depends on the comment's length)

Thanks.

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "For Discussion" or "Good first issue" and I will leave it open. Thank you for your contributions.

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

Was this page helpful?
0 / 5 - 0 ratings