React + Firebase 函数意外循环

React + Firebase function looping by accident

我不知道为什么我的函数在使用 useStates 时会循环, 任何人都可以找出问题所在。 It loops over and over,this is what appears in my console.log inside the snapshot

`function Classtab() {
  const [userName, setuserName] = React.useState(null)
  const [userType, setuserType] = React.useState(null)
  const [userEmail, setuserEmail] = React.useState(null)
  const [userCourse, setuserCourse] = React.useState([])
  const [registeredCourse, setregisteredCourse] = React.useState([])
  firebase.auth().onAuthStateChanged((user) => {
    if(user){
        var db = firebase.firestore()
        db.collection('user').doc(user.uid)
            .get()
            .then(snapshot => {
                          setuserName( snapshot.data().name)
                          setuserType( snapshot.data().type)
                          setuserCourse( snapshot.data().course)
                          setuserEmail( user.email)
                          console.log(userCourse)
                userCourse.map(course => {
                  db.doc(course).get().then(
                        snapshot => {setregisteredCourse([...registeredCourse, snapshot.data().name])}
                        )
                      }
                    )
      }).catch(error => console.log(error))}else{}
    })
  return(...)`

您需要将授权码移至useEffect。现在正在发生的事情是,您在每次渲染时都处于 运行 onAuthStateChanged 状态。每次 returns,它都会导致另一个渲染,导致它无限添加更多订阅。

我修改了您的代码以防止无限重新呈现并允许 userCourse 成为 promise.then 函数中的正确值。最初的情况是函数中的 userCourse 始终是一个空数组(由于闭包)。

function Classtab() {
  const [userName, setuserName] = React.useState(null);
  const [userType, setuserType] = React.useState(null);
  const [userEmail, setuserEmail] = React.useState(null);
  const [userCourse, setuserCourse] = React.useState([]);
  const [registeredCourse, setregisteredCourse] = React.useState([]);
  const registeredCourseRef = useRef(registeredCourse);
  useEffect(()=>{
    registeredCourseRef.current = registeredCourse;
  },[registeredCourse])
  useEffect(() => {
    const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        var db = firebase.firestore();
        db.collection('user')
          .doc(user.uid)
          .get()
          .then((snapshot) => {
            setuserName(snapshot.data().name);
            setuserType(snapshot.data().type);
            const userCourse = snapshot.data().course;
            setuserCourse(userCourse);
            setuserEmail(user.email);
            console.log(userCourse);
            userCourse.map((course) => {
              db.doc(course)
                .get()
                .then((snapshot) => {
                  setregisteredCourse((registeredCourse)=>[
                    ...registeredCourse,
                    snapshot.data().name,
                  ]);
                });
            });
          })
          .catch((error) => console.log(error));
      } else {
      }
    });
    return () => {
      unsubscribe();
    };
  //Need to have registeredCourse in the dependency array
  //Or have it in a ref
  }, []);
  // return(...)
}