Search code examples
react-nativeuse-effectuse-state

useEffect return an empty array


I'm trying to render data from my database

import React, { useState, useEffect } from 'react';
import { View, Text } from 'react-native';
import api from '../../Services/api';

function ProviderList(){
  const [provider, setProvider] = useState([]);

  async function loadingProvider(){
    const response = await api.get('providers');
    setProvider(response.data);
    console.log(provider);
  }

  useEffect(() => {
    loadingProvider();
  }, []);
  

  return(
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>{provider.name}</Text>   
    </View> 
    
  )
}

export default ProviderList;

When my page is rendered, the provider console.log is an empty array but when I save my project and the page reload, the data is returned. I read that it's because hooks are rendered right after the first page render, but I need to render this data when the page starts, and I don't know how to do it. Someone could help?


Solution

  • you error is log data

        setProvider(response.data);
        console.log(provider); //here the error
    


    you can't log state immediately after update it
    the doc say that

    Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately. setState() does not always immediately update the component. It may batch or defer the update until later

    for log listen for provider change like that

    useEffect(() => {
        console.log(provider); //log will work here
      }, [provider]);
    

    and you have another error here {provider.name}

    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>{provider.name}</Text> //provider is array not abject
        </View> 
    

    this will work for you

    import React, { useState, useEffect } from 'react';
    import { View, Text } from 'react-native';
    
    function ProviderList(){
      const [provider, setProvider] = useState([]);
    
      async function loadingProvider(){
        const response = {data : [1,2,3,4]}; //replace this with api
        setProvider(response.data);
      }
    
    
      useEffect(() => {
        console.log(provider); //log will work here
      }, [provider]);
      
    
      useEffect(() => {
        loadingProvider();
      }, []);
      
    
      return(
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>provider length is : {provider.length}</Text>   
        </View> 
        
      )
    }
    
    export default ProviderList;