0
votes

I would like to save user's data into state but for some reason is not working

I created this function to get the data from Firestore and then call it from a handleSubmit function in login component

function getUserData() {
   return db
     .collection("customers")
     .doc(currentUser.uid)
     .get()
     .then((doc) => {
       setUserData(doc.data());
     });
 }

If I console log userData after calling the function I get undefined, but if I console.log(doc.data()), I get the correct object. Any hint on what I am doing wrong will be much appreciated.

This is the handleSubmit function where the function is being called in the login form component:

const onSubmit = async (values) => {
    try {
      setError("");
      setLoading(true);
      await login(values.email, values.password);
      authenticateUser();

      await getUserData();

      console.log(userData);
      history.push("/");
    } catch {
      setError("Failed to log in");
    }

    setLoading(false);
  };```

2
Are you calling this function from within the component or is it separate from the component? Can you include the full component in your question?Sam R.
You will definitely need to show more code, especially where you are doing the logging. There should be enough information so that anyone can take the code and run it for themselves to reproduce the issue.Doug Stevenson
The function is declared in a context component and being called in an handleSubmit function form the login component. Just updated the post with further explanationsebagl

2 Answers

1
votes

I'm assuming setUserData is a useState hook function. If that's case, then it's an async function. That's why you are seeing data if you console log the doc.data(), but not userData.

If you want to wait until your userData exist before navigating to ('/') you can do the following. I would remove the await in front of getUserData because that's not doing anything.

useEffect(()=>{
  if (user) history.push("/")
},[user]);
0
votes

Any setState function is asynchronous so logging after it won't show values since it's still updating the state. To see an actual change you need an effect. Since userData is an object, regular useEffect will not work. What you need is something to watch changes in objects. That's where useDeepCompareEffect by Kent comes in.

import useDeepCompareEffect from 'use-deep-compare-effect'
...

const [userData, setUserData] = useState();
...
// This effect will do what you want when userData changes
useDeepCompareEffect(()=> { 
  if(userData) {
  // do whatever you want here if userData is defined or whatever logic you looking for
  history.push("/");
  }
}, [userData])