How to use await in dispatch using contextAPI?

I have a problem while redirecting user to dashboard, I just want to make sure that dispatch is completed and then i start redirecting user to another page. But i don’t know how to do that. I am new in react so please help me.

 const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const { dispatch } = useContext(AuthContext);
  const location = useLocation();
  const history = useHistory();

  const submit = (e) => {
    e.preventDefault();
    axios
      .post(`${process.env.REACT_APP_API_URL}/auth/login`, { email, password })
      .then((response) => {
        dispatch({
          type: "LOGIN_USER",
          payload: response.data.token,
        });
        let { from } = location.state || { from: { pathname: "/" } };
        history.replace(from);
      })
      .catch((error) => {
        console.log(error);
      });
  };

const reducer = (state, action) => {
  switch (action.type) {
    case "LOGIN_USER":
      sessionStorage.setItem("token", action.payload.token);
      break;
    case "LOGOUT":
      sessionStorage.removeItem("token");
      break;
    default:
      throw new Error();
  }
};

const AuthProvider = (props) => {
  const [state, dispatch] = useReducer(reducer);
  const [isLoggedIn] = useState(!!sessionStorage.getItem("token"));

  return (
    <AuthContext.Provider value={{ state, dispatch, isLoggedIn }}>
     ....

Any solution appreciated!

Answer

The cause is that dispatch will finish in next cycle. So you can’t do things right away.

As far as I can see, there might be two ways based on your code.

  1. put history.replace inside LOGIN_USER action. So that after you set token, do redirect.

  2. add a callback function to the payload. After set token, call the callback.

Here’s the snippet for using approach 2).

        dispatch({
          type: "LOGIN_USER",
          payload: {
            token:  response.data.token,
            callback: () => {
              let { from } = location.state || { from: { pathname: "/" } };
              history.replace(from);
            }
          }
        });

and in reducer do

    case "LOGIN_USER":
      sessionStorage.setItem("token", action.payload.token);
      action.payload.callback()
      break;

BTW i also notice, your payload needs to be an object, ex .

  { token: ..., }