Infinite Loop of Images using React and Firestore Database - How do I get my data?

Viewed 60

I am very new to react and I am working with firestore database and react. Currently, I am trying to display information from a nested collection. When I run my app I get an infinite loop of my image. I been trying different ways to get my information but I keep coming across errors. What I am doing wrong to cause this infinite loop and how can I successfully render my information. Thanks ! [my database][1]

import {firebaseLooper} from '../tools/firebaselooper';
import { usersCollection } from '../tools/firebase';
import { AuthContext } from "./AuthConnect";

const ViewOneAdventure = (props) => {
    const {currentUser, userDetails} = useContext(AuthContext);
    const [results, setResults] = useState([]);
    const currentLocationId = props.location.state.id

    useEffect(() => {
        //const unmount = 
        usersCollection
        .doc(currentUser.uid)
        .collection('locations')
        .doc(currentLocationId)
        .collection('dates')
        .get()
        .then((querySnapshot) => {
            querySnapshot.forEach((doc) => {
                // doc.data() is never undefined for query doc snapshots
                console.log(doc.id, " => ", doc.data());
                setResults([...results,doc.data()])
            });
        });
    });

        return(
            <div>
            <p>
            
            {results.map((result) => (
            <aside key={result.day}>
            <aside src={result.journalentry} />
            <img src={result.travelphotos} 
                alt="image">
            </img>
            </aside>
       ))}
       </p>
            </div>
        )
}
export default ViewOneAdventure;   ```


  [1]: https://i.stack.imgur.com/TkjL8.png
2 Answers

You useEffect is missing the dependency array so it's running each render cycle, and since it updates state, it triggers another render cycle. Add a dependency array.

Use an empty dependency array to run once when the component mounts:

useEffect(() => {
  usersCollection
    .doc(currentUser.uid)
    .collection('locations')
    .doc(currentLocationId)
    .collection('dates')
    .get()
    .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
            // doc.data() is never undefined for query doc snapshots
            console.log(doc.id, " => ", doc.data());
            setResults([...results,doc.data()])
        });
    });
}, []); // <-- empty dependency array to run once on mount

Or more likely you want the currentUser.uid as a dependency to run the effect on mount and when currentUser.uid updates:

useEffect(() => {
  usersCollection
    .doc(currentUser.uid)
    .collection('locations')
    .doc(currentLocationId)
    .collection('dates')
    .get()
    .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
            // doc.data() is never undefined for query doc snapshots
            console.log(doc.id, " => ", doc.data());
            setResults([...results,doc.data()])
        });
    });
}, [currentUser.uid]); // *

* add any missing dependencies any linters complain about, like maybe currentLocationId. It depends on what and when you want to update the results state.

You are updating using useState inside an useEffect with out passing any dependencies. This provokes an infinite loop. Please include [] or ["your dependencies"] after the useEffect. For example like this:

useEffect(() => {
  usersCollection
    .doc(currentUser.uid)
    .collection('locations')
    .doc(currentLocationId)
    .collection('dates')
    .get()
    .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
            console.log(doc.id, " => ", doc.data());
            setResults([...results,doc.data()])
        });
    });
}, [currentUser.uid]);
Related