0

I am very new to React and come across useReducer. If I paste my code here, it will be very long, because it involve component, useContext and useReducer.So I will paste some of the code only. I have question about the state in try and catch loop. My reducer fire up a login method that use firebase signInWithEmailAndPassword(). Am I doing the try and catch loop wrong? I am able to see the error message in the console.log, but my state won't update with the error message, neither in the then().catch() nor in the try and catch loop.

  const loginUser = (usename, password, state) => {
    try{

      const res = auth.signInWithEmailAndPassword(email, password).then( user => {
          return {...state, userid: user.uid}
        }).catch(error => {
              return {...state, error: error.message}
        })


    }catch (error) {
      console.log("oops !! error: ", error);
   
      return {...state, error: error, isLoggedIn:false, isLoading:false};
    }
}

export const storeReducer = (state, action) => {
    switch (action.type) {
      case USER_LOGIN: 
      
        return loginUser(action.username, action.password, state);
          
      default:
        return state;
    }
  };

The code above is a simplified version that I am facing problem with updating the state using useReducer.

user2601660
  • 29
  • 10

1 Answers1

0

I would change your loginUser function to something like this...

const loginUser = async (usename, password, state) => {
    try{
      const response = await auth.signInWithEmailAndPassword(email, password)

      return // return user here
    }catch (error) {
      console.log("oops !! error: ", error);
   
      return // return error here
    }
}

And you should dispatch an action based on the return of this function, or dispatch from this function. You should NOT place this function within your reducer as it is asynchronous, and your reducer should be a pure function

It should be more like...

loginUser.then(data => {
  // dispatch accordingly
})
Jason
  • 367
  • 1
  • 8
  • Thanks @Jason for the reply. I did the changes accordingly but it return Promise..How do I handle the Promise ? How do I get the value returned by the Promise ? – user2601660 Sep 25 '20 at 05:01
  • May I ask what are you returning? Or what code do you have after _awaiting_ response? – Jason Sep 25 '20 at 05:14
  • It returned the Promise with the correct state value, but the state value is not updated to the useContext value. Promise state value show at https://i.ibb.co/KmxLjx0/Promise.png while the context value is shown at https://i.ibb.co/RzZtw6g/Context.png – user2601660 Sep 25 '20 at 11:27
  • Hi Jason, the async await cause delay in getting the state. I tried many different approach using try/catch and async/await but to no avail. The state update is delayed in the useReducer when I use async/await and it returned initial state in useReducer. So,I switch to normal try/catch without async/await but add-in the `const currentUser = auth.currentUser` after the `const response = auth.signInWithEmailAndPassword(email,password)`. And it give me the result I wish to see.. Anyway, Thanks for your effort to help – user2601660 Oct 02 '20 at 08:13