Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FlatList calling twice

I have this code

class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {
        dataSource: []
    }
    this._handleRenderItem = this._handleRenderItem.bind(this);
    this._keyExtractor = this._keyExtractor.bind(this);
  }

  componentDidMount() {

    let success = (response) => {
        this.setState({ dataSource: response.data });
    };

    let error = (err) => {
        console.log(err.response);
    };

    listarProdutos(success, error);
  }

  _keyExtractor = (item, index) => item._id;

  _handleRenderItem = (produto) => {
    return (
        <ItemAtualizado item={produto.item} />
    );
  }

  render() {
    return (
        <Container style={styles.container}>
            <Content>
                <Card>
                    <CardItem style={{ flexDirection: 'column' }}>
                        <Text style={{ color: '#323232' }}>Produtos atualizados recentemente</Text>
                        <View style={{ width: '100%' }}>
                            <FlatList
                                showsVerticalScrollIndicator={false}
                                data={this.state.dataSource}
                                keyExtractor={this._keyExtractor}
                                renderItem={this._handleRenderItem}
                            />
                        </View>
                    </CardItem>
                </Card>
            </Content>
        </Container>
    );
  }
}

export default Home;

The function _handleRenderItem() is being called twice and I can't find the reason. The first time the values inside my <ItemAtualizado /> are empty, but the second was an object.

enter image description here

like image 289
Alessandro Macanha Avatar asked Jan 20 '18 14:01

Alessandro Macanha


People also ask

How do you optimize a FlatList performance?

The more complex your components are, the slower they will render. Try to avoid a lot of logic and nesting in your list items. If you are reusing this list item component a lot in your app, create a component only for your big lists and make them with as little logic and nesting as possible.

Does FlatList have onPress?

The ItemSeparatorComponent prop of FlatList is used to implement the separator between the elements of the list. To perform the click event on list items, we use onPress prop to Text.

How do I use extra data on FlatList?

flatlist-simpleBy passing extraData={selectedId} to FlatList we make sure FlatList itself will re-render when the state changes. Without setting this prop, FlatList would not know it needs to re-render any items because it is a PureComponent and the prop comparison will not show any changes.

What can I use instead of FlatList?

Meet FlashList! A FlatList alternative that runs on UI thread and, as they claim on their website, it runs 10x faster on JS and 5x faster on JS thread. Even considering only half the improvement — these are really great performance boosts. pod install if you need to replace your existing <FlatList> with <FlashList>.


2 Answers

This is normal RN behavior. At first, when the component is created you have an empty DataSource ([]) so the FlatList is rendered with that.

After that, componentDidMount triggers and loads the updated data, which updates the DataSource.

Then, you update the state with the setState which triggers a re render to update the FlatList.

All normal here. If you want to try, load the datasource in the constructor and remove the loading in the componentDidMount. It should only trigger once.

like image 153
sebastianf182 Avatar answered Oct 22 '22 04:10

sebastianf182


If you want to control render actions, you can use shouldComponentUpdate method.

For example:

shouldComponentUpdate(nextProps, nextState){ if(this.state.friends.length === nextState.friends.lenght) return false; }

it will break render if friends count not change.

like image 33
mrkacan Avatar answered Oct 22 '22 02:10

mrkacan