问题:React/Redux/Typescript - useDispatch 和 .then().catch()

我是 React/Redux 的初学者。我想对用户进行身份验证并在发生错误时在我的应用程序上显示通知。

这是我的登录功能:

  const [loading, setLoading] = useState(false);
  const dispatch = useDispatch();

  const handleSignIn = (values: SignInOpts, setSubmitting: any) => {
      setLoading(true);
      dispatch(authenticationActions.signInAndFetchUser(values))
        .then(res => {
          console.log("SignIn Success");
          setLoading(false);
        })
        .catch(err => {
          console.log("SignIn Failure");
          setLoading(false);
          showErrorNotification(
            "Error notification"
          );
        });
  };

我的行动:

export const signInAndFetchUser = (credentials: SignInOpts) => {
  return (dispatch, getState) => {
    return dispatch(signIn(credentials)).then(res => {
      const token = getState().authentication.token;
      return dispatch(getMe(token));
    });
  };
};

我遇到的错误:

React/Redux 错误

我该怎么做?

解答

您的大部分工作都应该发生在 thunk(动作)中。dispatch不返回承诺。所以你必须在你的 thunk 中处理你的 promise 并发送相应的动作,然后它会被发送到 reducer。新状态将反映更改。

这是一个 thunk,它应该让您了解它是如何工作的:

export const signInAndFetchUser = (credentials: SignInOpts) => {
  return (dispatch, getState) => {
    dispatch(action.startLoading);
    signIn(credentials)
      .then((res) => {
        // do something with res : maybe recover token, and store it to the store ?
        // if the token is in the store already why do you need to signIn ?
        dispatch(action.signedInSuccess(res.token));

        getMe(res.token)
          .then((user) => {
            dispatch(action.getMeSucceded(user));
          })
          .catch((err) => dispatch(action.getMeFailed(err)));
      })
      .catch((err) => dispatch(action.signInFailed(err)));
  };
};

或使用 async/await :

export const signInAndFetchUser = (credentials: SignInOpts) => {
  return async (dispatch, getState) => {
    dispatch(action.startLoading);

    try {
      const res = await signIn(credentials);
      dispatch(action.signedInSuccess(res.token));

      try {
        const user = await getMe(res.token);
        dispatch(action.getMeSucceded(user));
      } catch (err) {
        dispatch(action.getMeFailed(err));
      }
    } catch {
      dispatch(action.signInFailed(err));
    }
  };
};
Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐