Search code examples
javascriptreactjsreact-nativereact-hooksrealm

State only set on second render (react-native)


I'm pulling data from a Realm file db, but data seem to only appear on 2nd render. Here's my code:

import React, { useState, useEffect } from 'react'
import {getAllArchive} from '../Schemas/activitiesArchiveSchema';

const Stats = () => {
  const [Archives, setArchives] = useState();

  useEffect(() => {
    (async () => setArchives(await getAllArchive()))();
    console.log(JSON.stringify(Archives))
  }, []);

DB function:

export const getAllArchive = () => {
    return new Promise((resolve, reject) => {
        Realm.open(databaseOptions).then(realm => {
            let activitiesList = realm.objects(ARCHIVE_LIST_SCHEMA)
            resolve(activitiesList)
        }).catch((error) => reject(error))
    })
}

Output:

 LOG  undefined
 LOG  {"0":{"title":"sw2","records":{"0":{"date":"4/28/2021","seconds":7,"minutes":0,"hours":1},"1":{"date":"4/27/2021","seconds":7,"minutes":0,"hours":0},"2":{"date":"4/28/2021","seconds":7,"minutes":0,"hours":0}}},"1":{"title":"jj","records":{"0":{"date":"4/25/2021","seconds":0,"minutes":55,"hours":1}}},"2":{"title":"l,kl","records":{"0":{"date":"4/28/2021","seconds":4,"minutes":12,"hours":1}}},"3":{"title":"fsdfdsf","records":{"0":{"date":"4/25/2021","seconds":4,"minutes":43,"hours":1}}},"4":{"title":"sideProj","records":{"0":{"date":"4/26/2021","seconds":30,"minutes":29,"hours":1},"1":{"date":"4/27/2021","seconds":15,"minutes":18,"hours":1}}},"5":{"title":"work","records":{"0":{"date":"4/28/2021","seconds":36,"minutes":13,"hours":0},"1":{"date":"4/28/2021","seconds":37,"minutes":11,"hours":3}}},"6":{"title":"plp","records":{"0":{"date":"4/25/2021","seconds":2,"minutes":12,"hours":3}}},"7":{"title":"fff","records":{"0":{"date":"4/25/2021","seconds":3,"minutes":10,"hours":2}}},"8":{"title":"Work","records":{"0":{"date":"4/27/2021","seconds":1,"minutes":0,"hours":0}}},"9":{"title":"chilling","records":{"0":{"date":"4/27/2021","seconds":40,"minutes":4,"hours":3},"1":{"date":"4/27/2021","seconds":0,"minutes":0,"hours":0}}}}

Can someone point out any issues in the code plz? thx


Solution

  • This is not a surprise that your data is not loaded in the very first render of the component. First, let's see what useEffect does if you don't provide any dependency- it executes on every re-render.

    on this line of code:

    (async () => setArchives(await getAllArchive()))();
    

    you're fetching data that is asynchronous, the execution will not pause here. so, console.log(JSON.stringify(Archives)) will be executed. If Archived is still undefined (meaning data fetching is incomplete) you see LOG undefined. When, the asynchronous data fetching is completed and state updated what causes the component rerender hence useEffect is called again and you see

    LOG  {"0":{"title":"sw2","records":{"0":{"date":"4/28/2021","seconds":7,"minutes":0,"hours":1},"1":{"date":"4/27/2021","seconds":7,"minutes":0,"hours":0},"2":{"date":"4/28/2021","seconds":7,"minutes":0,"hours":0}}},"1":{"title":"jj","records":{"0":{"date":"4/25/2021","seconds":0,"minutes":55,"hours":1}}},"2":{"title":"l,kl","records":{"0":{"date":"4/28/2021","seconds":4,"minutes":12,"hours":1}}},"3":{"title":"fsdfdsf","records":{"0":{"date":"4/25/2021","seconds":4,"minutes":43,"hours":1}}},"4":{"title":"sideProj","records":{"0":{"date":"4/26/2021","seconds":30,"minutes":29,"hours":1},"1":{"date":"4/27/2021","seconds":15,"minutes":18,"hours":1}}},"5":{"title":"work","records":{"0":{"date":"4/28/2021","seconds":36,"minutes":13,"hours":0},"1":{"date":"4/28/2021","seconds":37,"minutes":11,"hours":3}}},"6":{"title":"plp","records":{"0":{"date":"4/25/2021","seconds":2,"minutes":12,"hours":3}}},"7":{"title":"fff","records":{"0":{"date":"4/25/2021","seconds":3,"minutes":10,"hours":2}}},"8":{"title":"Work","records":{"0":{"date":"4/27/2021","seconds":1,"minutes":0,"hours":0}}},"9":{"title":"chilling","records":{"0":{"date":"4/27/2021","seconds":40,"minutes":4,"hours":3},"1":{"date":"4/27/2021","seconds":0,"minutes":0,"hours":0}}}}