Search code examples
reactjsgoogle-cloud-firestoreuse-effectuse-state

react firestore - Unable to pass useEffect dependency / useState as prop to component


I'm trying to conditionally render a component using a useState prop when it is finished loading in my useEffect hook but I am having issues. I've tested my theory thus far and am able to render parts of the data once it is finished loading but I can't pass it as a prop to my component and when it is passed, it says it is undefined in the component. I'm trying to get the component to be able to render when the data has finished loading from Firestore.

Its throwing me for a loop that i cant render my component but i can conditionally render the other blocks below.

here is my code:

export default function Dashboard() {
  const [keys, setKeys] = useState(allKeys);
  const [user, loading, error] = useAuthState(auth);
  const [dataToShow, setData] = useState();

  const actionsPath = `Users/${user.uid}/XXXXXXXXX/`;

  let arrayActions = [];

  useEffect(() => {
    onSnapshot(collection(db, actionsPath), (snapshot) => {
      const docs = snapshot.docs;

      docs.forEach((doc) => arrayActions.push(doc.data())); // this works

      setData(arrayActions);
    });
  }, []);

return (
    <React.Fragment>
      
      <h1>Dashboard</h1>
      <h1>{user.displayName}</h1>
      <h1>{user.uid}</h1>
      <h2>
        <strong>Stat</strong>
      </h2>

      {/* able to conditionally render */}
      {dataToShow ? <p>Data is here</p> : <p>nothing</p>}

      {/* able to show the data */}
      {dataToShow ? dataToShow?.map((doc, index) => (
          <h1>{doc.Add}</h1>
        )) : <p>nothing</p>}

{/* block below shows an error and gives error: `Uncaught TypeError: csvData is not iterable`*/}
{dataToShow ? <Profile
        propsData={dataToShow} {/* shows undefined in console log in Profile Component */}
        keys={keys}
        colors={colors}
        height="600px"
      /> : <p>nothing</p>}
      

    </React.Fragment>
  );


Any and all help and direction is appreciated.


Solution

  • The ternary to check for dataToShow is passing (or it would render <p>nothing</p>) - so the data is being passed as a prop.

    {dataToShow ? <Profile
            propsData={dataToShow} {/* shows undefined in console log in Profile Component */}
            keys={keys}
            colors={colors}
            height="600px"
          /> : <p>nothing</p>}
    

    The error Uncaught TypeError: csvData is not iterable looks like the Profile component is specifically searching for a csvData object and trying to iterate through it - and failing.

    You should check (and share) your Profile component to see if csvData is hard-coded somewhere.

    Perhaps also possible is that you're using a library to handle the data in the Profile component. Are you using d3js by any chance?