0

EDIT: Now the daily page is blank and I'm getting an error of a.indexOf is not a function...no idea what that even means...

prebuilt-ac190846-5fb4dac2.js:719 Uncaught TypeError: a.indexOf is not a function
    at Function.t.fromString (prebuilt-ac190846-5fb4dac2.js:719)
    at Tu (prebuilt-ac190846-5fb4dac2.js:14976)
    at t.doc (prebuilt-ac190846-5fb4dac2.js:18193)
    at ConfidenceTexts.js:20
    at Os (react-dom.production.min.js:262)
    at t.unstable_runWithPriority (scheduler.production.min.js:18)
    at Qi (react-dom.production.min.js:122)
    at Rs (react-dom.production.min.js:261)
    at react-dom.production.min.js:261
    at L (scheduler.production.min.js:16)

I have looked at multiple tutorials, and I'm still a bit baffled on how to get my app to show what I want. I eventually want to have a database with a bunch of quotes, and my app to randomly pick one to display.

I have managed to setup a collection in Firestore that always has one doc called 'num' with a field called num and the value is a stringified number. I'm using a Firebase cloud function to update the value every so often (making it a random number).

I want to use that random number to display a quote from collection named 'texts'. Every quote's docname (id) is a stringified number, so I can use the value from num to get a quote. From what I can tell, it should be working, however, when I try to load the page that displays the quote, the console shows the number generating multiple times (usually 3-4, but sometimes more), the text updates every time it updates, and then it finally settles on a quote (but usually it's not even corresponding to the number from the random collection).

I have a feeling it has something to do with useState. I had a really hard time figuring out how to even display the data from Firestore, as it would give me an error saying I can't have a component can't return an object. Please advise on how I can fix this. I do have it currently deployed but the random number is set to update once a day. You'll be able to see how the quote changes before it settles on one (currently there are only 2 quotes in the database).

https://confidence-text-179ac.web.app/daily

Here's what I have:

import React, { useState } from 'react';
import firebaseConfig from './Config'
import firebase from "firebase/app";
import "firebase/firestore";

firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();

const ConfidenceTexts = () => {
    const [text,setText] = useState("")
    const [num,setNum] = useState(1)

    const number = db.collection("random").doc('num');

    number.get().then((doc) => {
        setNum(doc.data().num)
    });

    const docRef = db.collection("texts").doc(num);

    docRef.get().then((doc) => {
        setText(doc.data().text)
    });

    return (
        <div>
            {text}
        </div>
    )
};

export default ConfidenceTexts;

1 Answer 1

2

Every time you set state (update the state) your component is rerendering, and you get requests are being made again. Put your requests in a use effect with an empty conditional array so that the requests are only made on the first render.

useEffect(() => {
        number.get().then((doc) => {
            setNum(doc.data().num)
        });

        docRef.get().then((doc) => {
            setText(doc.data().text)
        });
    }, [])

If you want useEffect to run ONLY on the first render of the component, don't pass anything into your dependency array:

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

If you want useEffect to run on EVERY render, use this (no dependency array):

useEffect(() => {})

If you want useEffect to run on the first render of the component, AND on state(s) changes, pass dependency states into the array:

useEffect(() => {}, [state, anotherState])

If you are trying to avoid useEffect rendering on the first render, you need to use a UseRef hook. This post will tell you how to go about doing this.

Sign up to request clarification or add additional context in comments.

2 Comments

Now I'm getting an error saying a.indexOf is not a function
You also have an issue with trying to assign setState to a state in an unmounted component. You will need to add cleanup callbacks. Here is a good post for that issue: stackoverflow.com/questions/53949393/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.