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] Horizontal Paged FlatList does not render with initial items when passed as props from parent container or when passed as state, RN 0.43.2 #13386

Closed
whoyawn opened this issue Apr 7, 2017 · 8 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@whoyawn
Copy link

whoyawn commented Apr 7, 2017

Description

I'm creating a pager out of the FlatList. I have a function that adjusts each item of the list to the width of the screen. I'm manually passing a hard coded list for the data as props to have an initial render of the FlatList, but nothing actually shows up until I add another item to my list. The items should already be rendered when I start up the application.

Reproduction Steps and Sample Code

  1. Create a horizontal FlatList and adjust each page size with the screen when loaded
  2. Render the list with initial data

Code (missing a few imports)

-----
index.ios.js

import React, { Component } from 'react';
import {
  AppRegistry,
} from 'react-native';

import LogViewPager from './PageDetail'

export default class flatlisttest extends Component {
  state = {
    log: [{ key: 'page_one', date: 'tuesday', entries: [] },
      { key: 'page_two', date: 'tuesday', entries: [] }
    ]
  };
  render() {
    return (
      <LogViewPager log={this.state.log}
      onAddPage={() => this.setState({
        log: [...this.state.log,
          { key: Date.now(), date: 'tuesday', entries: [] }
          ]
        })
      }
      />
    );
  }
}

--------------
PageDetail.js

export default class LogViewPager extends Component {
  state: State;
  _listRef: FlatList<*>;

  constructor(props: Props) {
    super(props);
    this.state = {
      height: 0,
      width: 0,
      selectedIndex: 0,
    };
    (this: any).renderPage = this.renderPage.bind(this);
    (this: any).adjustPageSize = this.adjustPageSize.bind(this);
  }

  render() {
    return (
      <View style={{flex: 1}}>
        <FlatList
          ref={(flatList) => {
            this._listRef = flatList;
          }}
          data={this.props.log}
          onLayout={this.adjustPageSize}
          renderItem={this.renderPage}
          showsHorizontalScrollIndicator={false}
          removeClippedSubviews={false}
          horizontal
          pagingEnabled
          directionalLockEnabled
        />
        <Text>{'props gets passed down properly: ' + this.props.log[0].date}</Text>
        <TouchableOpacity style={{backgroundColor: 'red', paddingTop: 30}}
                          onPress={this.props.onAddPage}>
          <Text>+</Text>
        </TouchableOpacity>
      </View>
    );
  }
  adjustPageSize(e: any) {
    this.setState({
      height: e.nativeEvent.layout.height,
      width: e.nativeEvent.layout.width,
    });
  }

  renderPage({ item }): React.Element<any> {
    return (
      <PageDetail
        entries={item.entries}
        date={item.date}
        style={{ width: this.state.width }}
      />
    );
  }
}

class PageDetail extends React.PureComponent {

  render() {
    return (
      <View style={[styles.container, this.props.style]}>
        <Text>{'this is a page'}</Text>
      </View>
    );
  }
}

Additional Information

  • React Native version: "0.43.2"
  • Platform: iOS
  • Development Operating System: OS X

Related: #13316 and #13202

@whoyawn whoyawn changed the title [FlatList] Horizontal Paged FlatList does not render with initial items, RN 0.43 [FlatList] Horizontal Paged FlatList does not render with initial items, RN 0.43.2 Apr 7, 2017
@whoyawn whoyawn changed the title [FlatList] Horizontal Paged FlatList does not render with initial items, RN 0.43.2 [FlatList] Horizontal Paged FlatList does not render with initial items when passed as props from parent container, RN 0.43.2 Apr 8, 2017
@whoyawn
Copy link
Author

whoyawn commented May 6, 2017

As a note, removedClippedSubviews is also turned off, but the problem does not get fixed. I also discovered if I try loading the data prop with my list in the state,

constructor(props: Props) {
    super(props);
    this.state = {
      height: 0,
      width: 0,
      log: [{ key: 'page_one', date: 'tuesday', entries: [] },
        { key: 'page_two', date: 'tuesday', entries: [] }
      ]
    };
    (this: any).renderPage = this.renderPage.bind(this);
    (this: any).adjustPageSize = this.adjustPageSize.bind(this);
  }

...

render() { return ( <Flatlist data={this.state.log} > ) }

The page does not load either

@whoyawn
Copy link
Author

whoyawn commented May 6, 2017

Somehow I was poking around the example code, and came across this:

const filterRegex = new RegExp(String(this.state.filterText), 'i');
    const filter = (item) => (
      filterRegex.test(item.text) || filterRegex.test(item.title)
    );
    const filteredData = this.state.data.filter(filter);

so I tried to replicate that, and found that after reducing it to this (and applying my code):

const log = this.props.log.filter((item) => item);

and then just passing it to the FlatList, making the render function look like this:

render() {
  const log = this.props.log.filter((item) => item);
  return (
    <FlatList
          data={log}
          renderItem={this.renderPage}
       />
    )
}

the list items load perfectly fine. I have no idea why. Can someone try to replicate this and help me figure it out?

@whoyawn whoyawn changed the title [FlatList] Horizontal Paged FlatList does not render with initial items when passed as props from parent container, RN 0.43.2 [FlatList] Horizontal Paged FlatList does not render with initial items when passed as props from parent container or when passed as state, RN 0.43.2 May 6, 2017
@whoyawn
Copy link
Author

whoyawn commented May 6, 2017

Seems like any sort of transformative array operation will work:

So far I've tried [...this.props.log] and this.props.log.map(item => item) and both have been successful.

@alanwzou
Copy link

alanwzou commented May 8, 2017

The same problem, any solution already?

@whoyawn
Copy link
Author

whoyawn commented May 8, 2017

Another workaround I tried was to set the getItemLayout prop. That led to a few issues with the scrollTo methods but so far it works.

@dzuncoi
Copy link

dzuncoi commented May 11, 2017

@HuyAnhh
I think,
from the docs

This is a PureComponent which means that it will not re-render if props remain shallow-equal. Make sure that everything your renderItem function depends on is passed as a prop that is not === after updates, otherwise your UI may not update on changes. This includes the data prop and parent component state.

So if we use [...this.props.log] or this.props.log.map(item => item) in render method, the data passed in FlatList won't remain shallow-equal, hence FlatList will render correctly.

@whoyawn
Copy link
Author

whoyawn commented May 11, 2017

Shouldn't it render the first time though? from this.props.log = null to an object? If that were the case, I'd expect it to render once and then stay the same.

@hramos
Copy link
Contributor

hramos commented Jul 25, 2017

Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!

If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:

  • Does the issue still reproduce on the latest release candidate? Post a comment with the version you tested.
  • If so, is there any information missing from the bug report? Post a comment with all the information required by the issue template.
  • Is there a pull request that addresses this issue? Post a comment with the PR number so we can follow up.

If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.

@hramos hramos added the Icebox label Jul 25, 2017
@hramos hramos closed this as completed Jul 25, 2017
@facebook facebook locked as resolved and limited conversation to collaborators Jul 25, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 25, 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

5 participants