转换componentDidMount和componentWillUnmount

时间:2019-10-26 20:00:19

标签: reactjs react-hooks

我目前正在尝试使用React钩子来转换React + Material UI + Firebase模板。目前,我正在尝试将App.js中的生命周期方法转换为useEffect为止,这就是我所拥有的

useEffect(() => {
setMounted(true)

const removeAuthStateChangedObserver = auth.onAuthStateChanged((user) => {
  //* if there is no user...
  if (!user) {
    if (removeReferenceListener) {
      removeReferenceListener()
    }

    if (mounted) {
      setUser(null)
      setUserData(null)
      setSignedIn(false)
      setReady(true)
    }

    return

  }

  const uid = user.uid

  //* if there is no uid...
  if (!uid) {
    if (removeReferenceListener) {
      removeReferenceListener()
    }

    if (mounted) {
      setUser(null)
      setUserData(null)
      setSignedIn(false)
      setReady(true)
    }

    return

  }

  const reference = firestore.collection('users').doc(uid)

  //* if there is no reference...
  if (!reference) {
    if (this.removeReferenceListener) {
      this.removeReferenceListener();
    }

    if (mounted) {
      setUser(null)
      setUserData(null)
      setSignedIn(false)
      setReady(true)
    }

    return

  }

  const removeReferenceListener = reference.onSnapshot((snapshot) => { //!ADDED CONST HERE INSTEAD OF THIS
    if (!snapshot.exists) {
      if (removeReferenceListener) {
        removeReferenceListener();
      }

      if (mounted) {
        setUser(null)
        setUserData(null)
        setSignedIn(false)
        setReady(true)
      }

      return

    }

    const data = snapshot.data();

    if (!data) {
      if (removeReferenceListener) {
        removeReferenceListener();
      }

      if (mounted) {
        setUser(null)
        setUserData(null)
        setSignedIn(false)
        setReady(true)
      }

      return

    }

    if (mounted) {
      setUser(user)
      setUserData(data)
      setSignedIn(true)
      setReady(true)
    }

  })
})

//!FOR THE componentWillUnmount
return () => {
  if (removeAuthStateChangedObserver) {
    removeAuthStateChangedObserver();
  }

  if (removeReferenceListener) {
    removeReferenceListener();
  }

  setMounted(false);
}}, [mounted]) 

在这里,已经使用useState挂钩符号定义了我的变量,user,userData,signedIn,准备好了。我在使用ESlint时遇到一些错误,告诉我在方法检查之前放置声明,或者在componentWillUnmount的最终返回语句中未定义'removeReferenceListener'。

如果有人可以帮助我,这将非常重要,因为这是应用程序中注册用户最重要的方法之一。如果更有用,这是我已经拥有的link。谢谢

1 个答案:

答案 0 :(得分:0)

我已经用一些注释格式化了您的代码

useEffect(() => {
  const removeAuthStateChangedObserver = auth.onAuthStateChanged(
    user => {
      //* if there is no user...
      if (!user) {
        //why would you try to do this? This only runs on the first mount
        //  and you didn't create removeReferenceListener yet
        // if (removeReferenceListener) {
        //   removeReferenceListener();
        // }
        //just set the state, App will never unmount
        setUser(null);
        setUserData(null);
        setSignedIn(false);
        setReady(true);

        return;
      }

      const uid = user.uid;

      //* if there is no uid...
      if (!uid) {
        //again trying to call removeReferenceListener when it wasn't created
        //  yet
        // if (removeReferenceListener) {
        //   removeReferenceListener();
        // }

        setUser(null);
        setUserData(null);
        setSignedIn(false);
        setReady(true);

        return;
      }

      const reference = firestore
        .collection('users')
        .doc(uid);

      //* if there is no reference...
      if (!reference) {
        //you still didn't create removeReferenceListener, why keep trying to
        //  call it?
        // if (removeReferenceListener) {
        //   removeReferenceListener();
        // }

        setUser(null);
        setUserData(null);
        setSignedIn(false);
        setReady(true);

        return;
      }
      //now you finally create removeReferenceListener and you want to call this
      //  if App unmounts, but App never unmounts?
      const removeReferenceListener = reference.onSnapshot(
        snapshot => {
          //!ADDED CONST HERE INSTEAD OF THIS
          if (!snapshot.exists) {
            if (removeReferenceListener) {
              removeReferenceListener();
            }

            setUser(null);
            setUserData(null);
            setSignedIn(false);
            setReady(true);

            return;
          }

          const data = snapshot.data();

          if (!data) {
            if (removeReferenceListener) {
              removeReferenceListener();
            }

            setUser(null);
            setUserData(null);
            setSignedIn(false);
            setReady(true);

            return;
          }

          setUser(user);
          setUserData(data);
          setSignedIn(true);
          setReady(true);
        }
      );
    }
  );

  //!FOR THE componentWillUnmount
  //  WHY? show me how the component will unmount
  return () => {
    if (removeAuthStateChangedObserver) {
      removeAuthStateChangedObserver();
    }
    //removeReferenceListener is not even in scope here, you could put it in scope
    //  but why would you? Returning a cleanup function is pointless because
    //  App will only mount once and never unmount
    // if (removeReferenceListener) {
    //   removeReferenceListener();
    // }
  };
}, []);