Array in useState comes out empty after setting it in a useState when calling it from a different function on user event

Viewed 41

Array in useState comes out empty after setting it from initial call upon component rendering.

After setting the array in the useState (and confirming it holds elements inside) the child component is rendered. Upon a user event a function in the parent component is called, and the array in the useState is printed.

However, the array comes out empty (the initial state) even though we set it and confirm in a useEffect, that it has been set.

I understand that setting useStates is a "async" event, but since this is a user event triggering the state tons of time after setting the array (which is a very small array) it still comes out empty.

As suggested in other similar questions the suggestions I have seen, is to call the array from a useEffect. However, this is not a possibility for me, since the Array has to be accessed from a function triggered by a user event.

Code:

import React, { useEffect, useState } from 'react';

const parentComponent = () => {


  const [array, setArray] = useState([]);

  // init useEffect
  useEffect( () => {
    dataBaseCall();
  }, [])

  useEffect( () => {

    // Print database respond when setting the array
    console.log(array);

  }, [array])

  const addObjectToArray = () => {
    const objToAdd = {
      onClickFunction : onClickFunction
    }

  // Push objToAdd into empty array
  setArray( (prevState) => [...prevState, objToAdd])
  }

  const dataBaseCall = async () => {

    Reponse can be empty array
    const arrayFromDatabase = await getArrayFromDatabase("someendpoint");

    if (arrayFromDatabase.length === 0) {
     addObjectToArray();
    } else {

    // Prints [{...}, {...}, ...]
    console.log(arrayFromDatabase);

   // If response is not empty each obj element looks like this:
   // { onClickFunction : onClickFunction }

    // Print expected array once setting it in init function
    setArray(arrayFromDatabase);
    }
  }

  // Called when user clicks button in child component
  const onClickFunction = () => {

    // Prints empty array (inital State)
    console.log(array);

  }


  return (
    <>
      {
        array.length > 0 && array.map( (props) => {
          return <SomeChildComponent {...props} />
        })
      }
    </>
  )
}

Child component:

import { useState } from 'react';

const SomeChildComponent= ({ onClickFunction }) => {
  
  const [tableRows, setTableRows] = useState([])

  const submitTableRow = () => {
    
    if (tableRows.length === 0) {
      
      // Call parent component
      onClickFunction();
    }
    
    setTableRows( (prevState) => [...prevState, {...}])
    
  }

  return (
    <>
      <SomeInputField />
      <SomeInputField />
      <SomeInputField />
      <SomeInputField />
      
      <Button onClick={submitTableRow}>Submit</Button>

      {
        tableRows.length > 0 && tableRows.map( (row) => {
          return <TableRowComponent row={row} />
        })
      }
      
    </>
  );
};
0 Answers
Related