Reactjs 针对多个功能的React useEffect清理

Reactjs 针对多个功能的React useEffect清理,reactjs,firebase,firebase-authentication,react-hooks,Reactjs,Firebase,Firebase Authentication,React Hooks,我有一个处理Firebase身份验证的useEffect。 当我注销然后再次登录时,我看到这个效果被调用了两次。每次我注销和重新登录时,都被称为额外时间 我觉得我需要用一个清理函数来处理这个问题,但我不知道如何编写它 这是我的钩子: useEffect(() => { console.log('RUNNING THE EFFECT'); function routeUser(user) { // Redirect user somewhere depending on us

我有一个处理Firebase身份验证的useEffect。 当我注销然后再次登录时,我看到这个效果被调用了两次。每次我注销和重新登录时,都被称为额外时间

我觉得我需要用一个清理函数来处理这个问题,但我不知道如何编写它

这是我的钩子:

useEffect(() => {
  console.log('RUNNING THE EFFECT');
  function routeUser(user) {
    // Redirect user somewhere depending on user state
  }
  function setupUser(user: User) {
    // sets the user state object
    routeUser(user);
  }
  if (!user) {
    firebase.auth().onAuthStateChanged((authUser) => {
      if (authenticatedUser) {
        callGraphQLMethod({ variables: { uid: authUser.uid, phoneNumber: authUser.phoneNumber } })
          .then(async (document) => {
            setupUser(...);
          });
      }
    });
  } else {
    // User object is already in state. use that instead
  }
  return () => {
    // >>>>>>>> How do I clean all this up?
  } 
}, [callGraphQLMethod, setUser, user]);

很多时候,像这样的函数会返回一个cleanup函数来取消对资源的订阅。
onAuthStateChanged的情况似乎也是如此


如果在效果内部设置状态,则它将渲染,因为它有一个新的状态值,但效果未附加到每个用户状态。也就是说,为什么我越来越多地重播。如果我注销并返回100次,此效果将运行100次。这正常吗?每次效果运行时,您都在添加另一个
onAuthStateChanged
回调。您可能只希望在安装组件时运行该部分效果一次。处理具有依赖性的效果中的其他函数。每次更改组件中的状态时,它将重新渲染,每次更改组件的道具时,它将重新渲染(当然,如果需要,在某些情况下,您可以使用React.memo部分停止此行为)但是,如果您正在加载一个组件,然后在装载时获取一个值并将其设置为状态,则reacts就是这样工作的,它将重新加载以向您显示它的结果normal@DrewReese那又是什么呢?这就是我需要清理的吗?太棒了。你能解释一下退订是做什么的吗。它与onAuthStateChanged函数的关系。我知道“?”是检查它是否存在,但什么是“()”?@Ben可选链接(
?。
)运算符检查函数,即,您可以
取消订阅(
)而不是
取消订阅(
)。
onAuthStateChanged ( nextOrObserver :  Observer < any > | ( ( a : 
  User | null ) => any ) ,  error ? :  ( a :  Error ) => any , 
  completed ? :  firebase.Unsubscribe ) : firebase.Unsubscribe
useEffect(() => {
  let unsubscribe;

  ...

  if (!user) {
    unsubscribe = firebase.auth().onAuthStateChanged((authUser) => {
      ...
    });
  } else {
    ...
  }

  return () => {
    unsubscribe?.();
  } 
}, [callGraphQLMethod, setUser, user]);