Flatlist does not render data when launching the Application - Firebase integration

Asked

Viewed 227 times

0

Good afternoon guys, I was studying the React Native Firebase library in order to learn how to work with a Firebase integration with React Native. However, I am facing some problems, the goal is to add the data in the Realtime Database through a screen and then take the data stored in the database to present on the Home screen using a Flatlist (something that should be simple), but the big problem is that the application does not render the data already stored when it first opens, that is when it starts the App. The data is rendered by Flatlist only when I navigate to the add screen and add a new item to the database (so it renders the newly added and existing ones) or when I perform a "Refresh" in the App (Giving a CTRL+S in the IDE or reloading the App in the emulator). In trying to solve the problem I did some tests and from what I understood The Flatlist takes the data stored in the state when it is still empty, ie did not receive the data from the firebase yet, even having already made the request. I tried to use asynchronous functions to try to solve, but without success, so I decided to turn to you, I will make available the most basic code I did (which in my conception should work). I already ran the App on my physical device, believing it was an emulator problem, but the problem persisted. Follows the code originally used:

import React, { useState } from 'react';  
import styled from 'styled-components/native';

import database from '@react-native-firebase/database';

const Container = styled.SafeAreaView`
    flex:1;
    justify-content:center;
`;

const Texto = styled.Text`
    margin:20px;
`;

const Lista = styled.FlatList``;

const Botao = styled.Button`

`;

const HomeScreen = (props) => {

    const [vetor, setVetor] = useState([])

    database().ref('users').on('value', (snapshot) => {

        snapshot.forEach((childItem)=>{

            vetor.push({
                name:childItem.val().name,
                idade:childItem.val().idade
            })
        })

        setVetor(vetor)
    })

    const mudarTela = () => {
        props.navigation.reset({
            routes:[{name:'Tela2'}]
        })
    }

    return (
        <Container>
           <Lista data={vetor} renderItem={({item})=><Texto>{item.name} idade: {item.idade}</Texto>}/>
            <Botao title='Tela de Adição' onPress={()=>mudarTela()} />
        </Container>
    );
}

export default HomeScreen;

It should be noted that I’m new to the Framework and this is one of my first posts here, so forgive any mistakes I’ve made.

1 answer

0

There is a problem in your code, I do not know if it will solve the problem:

The state vetor is immutable, and should only be modified by the function setVetor. You’re giving a push in vetor which seems to have no effect.

In this sense, create a temporary variable to store the result, and then update the result at the end. Something like this,

database()
  .ref('users')
  .on('value', (snapshot) => {
    const data = [];
    snapshot.forEach((childItem) => {
      data.push({
        name: childItem.val().name,
        idade: childItem.val().idade,
      });
    });

    setVetor(data);
  });

  • Thank you for the reply Pedro Henrique, I will test. But I was able to solve the problem by re-creating the component using classes instead of function and React Hooks. I kept the same logic, I made only the appropriate changes to the component to work with classes and it worked perfectly.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.