dispatch: Dispatch<AnyAction> 为什么有时你必须精确操作?

dispatch: Dispatch<AnyAction> why sometime you have to precise the Action?

我遇到了问题,可能是因为我正在尝试使用打字稿(输入 redux 的东西)做一些新的事情,

这是我的错误信息:Argument of type '(dispatch: Dispatch<AnyAction>) => Promise<string>' is not assignable to parameter of type 'AnyAction'. Property 'type' is missing in type '(dispatch: Dispatch<AnyAction>) => Promise<string>' but required in type 'AnyAction'. TS2345

这里的问题是我真的不明白为什么我会收到这个错误,因为 typeScript 只会在这个错误上抛出错误,而不会在另一个上抛出错误,所以我很困惑。

我的代码(有错误):

/Action/userAction.js
___________________________________________________
export const signOut = () => async (dispatch: Dispatch) => {
  try {
    dispatch(UserSignoutAction());
    dispatch(InitialErase());
    dispatch(signOutSessionInitial());
    dispatch(isLogout());
    persistor.flush();
    return "done";
  } catch (e) {
    const error = await e;
    throw error;
  }
};

/NavBar/container.js
_______________________________________________
const mapDispatchToProps = (
  dispatch: Dispatch
): {
  signOut: () => Promise<String>;
} => ({
  signOut: () => dispatch(signOut()),
});

这个例子抛出一个错误,我可以用 signOut: () => dispatch<any>(signOut()), 修复 我可以理解我需要输入 dispatch ok(但不知道我需要什么,但目前这就是我输入 any 的原因)

其他代码(无错误):

/Action/userAction.js
___________________________________________________
export const sessionInitial = (
  session_id: number
): sessionInitialActionOption => ({
  type: SESSION,
  payload: session_id
});

/Dashboard/container.js
_______________________________________________
const mapDispatchToProps = (
  dispatch: Dispatch
): {
  sessionInitial: (
    session_id: number
  ) => {
    type: string;
    payload: number;
  };
} => ({
  sessionInitial: (session_id: number) => dispatch(sessionInitial(session_id))
});

我想我的错误是我想通过一个函数执行多个Actions Creator。我认为这不是这样做的好方法,或者这个解决方案还可以,但对于 mapDispatchToProps.

中的 put/call 来说是荒谬的

感谢您帮助我理解这部分的工作原理它非常复杂。


___________________________Solution?____________________________


我根据 Hassan Naqvi 的提示找到了解决方案!以下代码对我有用:

const mapDispatchToProps = (
  dispatch: ThunkDispatch<
    void,
    void,
    | UserActionsType            //one of my actionsType
    | sessionActionsType         //one of my actionsType
    | isConnectActionsType       //one of my actionsType
    | initialUserActionsType     //one of my actionsType
  >
): {
  signOut: () => void;
} => ({
  signOut: () => dispatch(signOut())
});

type ApplicationDispatch = ThunkDispatch<IStoreState, void, AnyAction> & Dispatch

const mapDispatchToProps = (
  dispatch: ApplicationDispatch
): {
  signOut: () => void;
} => ({
  signOut: () => dispatch(signOut())
});

export default compose<any>(
  withRouter,
  connect(mapStateToProps, mapDispatchToProps)
);

我真的不明白为什么那个有效而不是上面的步骤...但我仍然会尝试理解为什么 redux-thunk?以及为什么 redux 中的 Dispatch 不够(可能是因为 actionsType included/send 具有函数 ThunkDispatch)为什么不直接替换 'any' signOut: () => dispatch<any>(signOut())通过动作类型? (不适合我)

DispatchThunkDispatch有什么区别?

感谢大家阅读这篇文章 post 希望我能读到一些 post 会改变我生活的人!放纵自己。祝你有美好的一天!


-正如你在上面看到的,当你使用redux-thunk来处理异步动作时,动作到达了最内层的函数actionFunction,它负责执行动作。但是这个调度是我们在中间件中创建的东西,而不是来自 createStore 的调度,它有监听器并将值传递给 reducer。

-reducer 的调度发生在它的父函数 nextFunction 中。

(来源:https://medium.com/@gethylgeorge/understanding-how-redux-thunk-works-72de3bdebc50

其他有用的 link : https://daveceddia.com/what-is-a-thunk/

所以如果我真的明白发生了什么,ThunkDispatch 可以执行fct,async fct 或不执行Dispatch 异常。 Dispatch 正在调用 Actions Creator 到 reducer。

如果我有什么不明白的地方告诉我,我会改正。

希望对您有所帮助!

问题是,您在 mapDispatchToProps 中的第一个参数使用类型 Dispatch

由于您正在使用 redux-thunk,因此您需要使用从 redux-thunk 导入的 ThunkDispatch 类型。

所以你的 NavBar/container.ts 应该变成:

import { AnyAction } from "redux";
import { ThunkDispatch } from 'redux-thunk';

// ApplicationState is the shape of your redux store.
// You can use any but its recommended to have a specified shape
// This should ideally be in a different file since it could be needed in many places
interface ApplicationState {
   username: string;
   userId: string;
}

// Use ApplicationDispatch everywhere instead of Dispatch
type ApplicationDispatch = ThunkDispatch<ApplicationState, void, AnyAction> & Dispatch

const mapDispatchToProps = (
  dispatch: ApplicationDispatch
): {
  signOut: () => Promise<String>;
} => ({
  signOut: () => dispatch(signOut()),
});