首页 > 解决方案 > 如何停止使用 Firebase 重新渲染 React 应用程序?

问题描述

编辑:现在每日页面是空白的,我收到错误 a.indexOf is not a function...不知道这甚至意味着什么...

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)

我查看了多个教程,但我仍然对如何让我的应用程序显示我想要的内容感到有些困惑。我最终想要一个包含一堆引号的数据库,并且我的应用程序可以随机选择一个来显示。

我设法在 Firestore 中设置了一个集合,该集合始终有一个名为“num”的文档,其中包含一个名为 num 的字段,并且该值是一个字符串化数字。我正在使用 Firebase 云函数每隔一段时间更新一次值(使其成为随机数)。

我想使用该随机数来显示名为“文本”的集合中的引用。每个报价的 docname (id) 都是一个字符串化的数字,所以我可以使用 num 中的值来获取报价。据我所知,它应该可以正常工作,但是,当我尝试加载显示报价的页面时,控制台会显示多次生成的数字(通常是 3-4,但有时更多),每次都会更新文本更新,然后它最终确定一个报价(但通常它甚至不对应于随机集合中的数字)。

我感觉它与 useState 有关。我很难弄清楚如何甚至显示来自 Firestore 的数据,因为它会给我一个错误,说我不能让组件不能返回对象。请告诉我如何解决这个问题。我目前确实部署了它,但随机数设置为每天更新一次。您将能够看到报价在确定一个报价之前是如何变化的(目前数据库中只有两个报价)。

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

这是我所拥有的:

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;

标签: node.jsreactjsfirebasegoogle-cloud-firestore

解决方案


每次您设置状态(更新状态)时,您的组件都会重新渲染,并且您会再次发出请求。使用空条件数组将您的请求置于使用效果中,以便仅在第一次渲染时发出请求。

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

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

如果您希望 useEffect 仅在组件的第一次渲染时运行,请不要将任何内容传递到您的依赖项数组中:

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

如果您希望 useEffect 在每个渲染上运行,请使用此(无依赖数组):

useEffect(() => {})

如果您希望 useEffect 在组件的第一次渲染时运行,并且在状态更改时运行,请将依赖状态传递到数组中:

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

如果您试图避免在第一次渲染时使用 useEffect 渲染,则需要使用 UseRef 挂钩。这篇文章将告诉你如何去做。


推荐阅读