skip to Main Content
    useEffect(() => {
      console.log("this is first useEffect", "first");
  });

  useEffect(() => {
    console.log("this is second useEffect", "second");
  });

  useEffect(() => {
    const listen = onAuthStateChanged(auth, (user) => {
      setLoading(true);
      if (user) {
        setAuthUser(user);
        setLoading(false);
        console.log("this is third useEffect",user)
      } else {
        setAuthUser(null);
      }
    });

    return () => {
      listen();
    };
  }, []);

  useEffect(() => {
    const db = getDatabase();

    const userId = authUser;
    console.log("this is fourth useEffect", userId);
    const starCountRef = ref(db, `users/${userId}/addressData`);
    onValue(starCountRef, (snapshot) => {
      const addresslist = [];
      snapshot.forEach((childSnapshot) => {
        const keyName = childSnapshot.key;
        const data = childSnapshot.val();
        addresslist.push({ key: keyName, data: data });
      });
      setSavedAddress(addresslist);
    });
  }, []);

I am using console log to check which useEffect is running first, but seems the fourth is rendering before third.
I want third to run first as fourth is depend on third

enter image description here

2

Answers


  1. The effects always run in order. The reason you’re getting logs out of order is that you’re logging unrelated things. In effects 1, 2, and 4 you’re logging right away, while the effect is running. In effect 3, you set up an onAuthStateChanged listener, and then do nothing else. No log happens while effect 3 is running. Some time later, the listener gets called and will set state and do a log.

    Since you’re setting state, the component rerenders. You can then use this to subscribe to the database in your 4th effect. Make sure to

    • Change the dependency array so the effect can rerun
    • Check for whether there’s a user or not, because the first render won’t have one.
    • Return an unsubscribe function so the effect can clean up correctly
      useEffect(() => {
        const db = getDatabase();
        const userId = authUser;
    
        if (!userId) {
          return; // <----
        }
    
        const starCountRef = ref(db, `users/${userId}/addressData`);
        const unsubscribe = onValue(starCountRef, (snapshot) => {
          const addresslist = [];
          snapshot.forEach((childSnapshot) => {
            const keyName = childSnapshot.key;
            const data = childSnapshot.val();
            addresslist.push({ key: keyName, data: data });
          });
          setSavedAddress(addresslist);
        });
    
        return unsubscribe; // <----
      }, [authUser]); // <----
    
    Login or Signup to reply.
  2. If you try to log third useEffect right after open curly brace, then you can see the ordered result.
    Because the onAuthStateChanged is not run when component is created.

    useEffect(() => {
        // console here
        console.log("this is third useEffect")
        const listen = onAuthStateChanged(auth, (user) => {
          setLoading(true);
          if (user) {
            setAuthUser(user);
            setLoading(false);
            console.log("this is third useEffect",user)
          } else {
            setAuthUser(null);
          }
        });
    
        return () => {
          listen();
        };
      }, []);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search