useEffect 永远运行

useEffect runs forever

我是 React.js 的新手。 我今天有一个关于 useEffect 的问题。 我知道如果我传递一个空的 [] 作为第二个参数,useEffect 只会运行一次。 但是,我的应用程序运行得太频繁,如果我 console.log(something),我可以看到。这是我的代码。请看第 19 行。 [] 在那里。我尝试在 [] 中添加测验,例如 [quizzes]。

import { useEffect, useState } from 'react';
import { doc, collection, onSnapshot } from 'firebase/firestore';

import db from '../firebaseConfig';

const Quiz = () => {
  const [quizes, setQuizes] = useState([]);
  useEffect(() => {
    const collectionRef = collection(db, 'quizes');
    const unsub = onSnapshot(
      collectionRef,
      snapshot => {
        setQuizes(
          snapshot.docs.map(
            doc => ({ ...doc.data(), id: doc.id })
          )
        );
      },
      []
    );
    return unsub;
    // getData(): run once
    // onSnapshot(): listen for realtime updates
  });

  console.log(quizes)

  return (
    <div className='quiz'>
      {quizes.map(quiz => (
        <div key={quiz.id} className='quiz'>
          {quiz.correctAns}
        </div>
      ))}
    </div>
  );
};

export default Quiz;

您有错字,您错放了空数组并将其传递给 onSnapshot() 调用而不是 useEffect() 调用。

此外,您应该确保将侦听器附加到 onSnapshot 的两个事件 - nexterror。当您不使用如下所示的观察者对象时,这些是 onSnapshot 调用的第二个和第三个参数。

// the recommended onSnapshot form in React
const unsub = onSnapshot(
  ref,
  {
    next: (snapshot) => { /* ... */ },
    error: (err) => { /* ... */ }
  }
);
// OR, the more confusing as your handlers grow in size:
const unsub = onSnapshot(
  ref,
  (snapshot) => { /* ... */ },
  (err) => { /* ... */ }
);
useEffect(
  () => {
    const collectionRef = collection(db, 'quizes');
    const unsub = onSnapshot(
      collectionRef,
      {
        next: (snapshot) => {
          setQuizes(
            snapshot.docs.map(
              doc => ({ ...doc.data(), id: doc.id })
            )
          );
        },
        error: (err) => {
          // don't forget error handling! e.g. update component with an error message
          console.error("quizes listener failed: ", err);
        }
      }
    ); // <-- not here
    return unsub;
    // getData(): run once
    // onSnapshot(): listen for realtime updates
  },
  [] // <-- empty array goes here, not in onSnapshot
);